问题
I have a form which when loaded starts a looping background worker which gets data from a usb device every half a second.
Once the program receives a new piece of data from the usb device it runs a function.
The _Dowork function has
while (true)
{
portConnection.Write("?");
Thread.Sleep(50);
}
I then have a separate routine that runs when data is received
private void portConnection_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
}
This is the routine that cannot then set values on the original form as the function is apparently on a separate thread.
How can I make this routine able to influence the original form?
回答1:
Try something like this:
private void InvokeIfRequired(Control target, Delegate methodToInvoke)
{
if (target.InvokeRequired)
target.Invoke(methodToInvoke);
else
methodToInvoke.DynamicInvoke();
}
Call the method in your ProcessStatsReceived and in the methodToInvoke do your stuff...
You can use it like this in the ProccessStatusReceived:
InvokeIfRequired(this, new MethodInvoker(delegate() { this.lblStatus.Text = (string)e.Data; }));
回答2:
The report progress part of BackgroundWorker is made for this.
This will make the DoWork method able to call a method on the GUI thread.
See this msdn article for details.
In short, the needed parts are:
Bind the progress changed handler:
bw.ProgressChanged += bw_ProgressChanged;
Set the BW to allow progress reporting:
bw.WorkerReportsProgress = true;
Implement the progress change method:
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//your logic to be executed on the GUI thread here
}
Then call it from DoWork like this:
bw.ReportProgress( progressPercentage, userState )
progressPercentage and userState can be user to transfer data from the background thread to the ProgressChanged method on the GUI thread.
来源:https://stackoverflow.com/questions/11842373/changing-a-form-from-a-separate-background-worker