问题
I need to invoke this: string input_ip_r = listView1.Items[lc].SubItems[1].Text;
so I used
if (InvokeRequired)
{
this.Invoke(new MethodInvoker(function));
return;
}
This worked but now I have put it into a BackgroundWorker
and using this
if (InvokeRequired)
{
this.Invoke(new MethodInvoker(bw.RunWorkerAsync));
return;
}
it gives an error that you can only run BackgroundWorker
one at a time.
So how do I invoke while in the Backgroundworker
?
回答1:
I'm not quite sure how you want to use the values, but just to give you an example, you could easily just do this in the BackgroundWorker
thread:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string input_ip_r = "";
this.Invoke(new Action(() =>
{
// Don't know what "lc" is (a loop variable?)
input_ip_r = listView1.Items[lc].SubItems[1].Text;
}));
}
See this answer for other ways of doing the same (this is for >= .Net 3.5)
回答2:
1) Don't put RunWorkerAsync
as the method to invoke. It's not actually running the method that you think. What you should really put there is something like this:
this.Invoke(new MethodInvoker(MethodToUpdateUI));
MethodToUpdateUI
should be some new method that you create that specifically does whatever UI updates should be made in this context.
2) There's no need for InvokeRequired
. You're in a background thread. Invoking will always be required.
To be honest, the entire patter of if(invoke required) call myself else do stuff
is an odd construct which I dislike. InvokeRequired
should pretty rarely be used. You should almost always know whether you're in the UI thread or a background thread, if you don't, chances are something wrong (either you're always in one or the other and you just don't know which, or it shouldn't be non-deterministic). Usually this means having methods that must be run in the UI thread. If you're already in the UI thread you just call them, if you're in a background thread and know it then you call Invoke
first.
On top of that, Invoke
works just fine even if you call it when you're already in the UI thread, so there's really no significant negative consequences to just calling Invoke
regardless of whether you're in a background thread or already in the UI thread.
3) Usually it's best to separate code for solving business problems from UI code. It's code smell to be invoking from within DoWork's handler. If this is right near the end, you should probably be adding an event handler to RunWorkerCompleted
. If you're calling this periodically to update the UI with progress of the worker, you should be using ReportProgress
and handling the ProgressReported
event. For getting info from the UI for use in a long running task you should access it before starting the background task. For exceptional cases that aren't any of those, it may be appropriate to use Invoke
, but the remaining cases ought to be rare.
来源:https://stackoverflow.com/questions/13960435/invoke-during-background-worker