Das*_*abs 2 c# background invoke worker
我需要调用它:string input_ip_r = listView1.Items[lc].SubItems[1].Text;
所以我用过
if (InvokeRequired)
{
this.Invoke(new MethodInvoker(function));
return;
}
Run Code Online (Sandbox Code Playgroud)
这有效,但现在我把它放入BackgroundWorker并使用它
if (InvokeRequired)
{
this.Invoke(new MethodInvoker(bw.RunWorkerAsync));
return;
}
Run Code Online (Sandbox Code Playgroud)
它会给出一个错误,您一次只能运行BackgroundWorker一个错误.
那么我如何调用Backgroundworker?
1)不要把它RunWorkerAsync作为调用的方法.它实际上并没有运行您认为的方法.你应该真正把它放在那里是这样的:
this.Invoke(new MethodInvoker(MethodToUpdateUI));
Run Code Online (Sandbox Code Playgroud)
MethodToUpdateUI 应该是您创建的一些新方法,具体应该在此上下文中进行任何UI更新.
2)没有必要InvokeRequired.你是一个后台线程.始终需要调用.
说实话,整个模式if(invoke required) call myself else do stuff是一个奇怪的结构,我不喜欢. InvokeRequired应该很少使用.你应该几乎总是知道你是在UI线程还是后台线程,如果你没有,可能是错的(要么你总是在一个或另一个,你只是不知道哪个,或者它不应该是非确定性的).通常这意味着必须在UI线程中运行方法.如果你已经在UI线程中,你只需要调用它们,如果你在后台线程中并且知道它,那么你Invoke先调用它.
最重要的是,Invoke即使你已经在UI线程中调用它也可以正常工作,所以Invoke无论你是在后台线程还是已经在UI线程中,对于调用都没有明显的负面影响.
3)通常最好将用于解决业务问题的代码与UI代码分开.从DoWork的处理程序中调用代码气味.如果这是接近结束,你可能应该添加一个事件处理程序RunWorkerCompleted.如果您定期调用此方法以使用工作进度更新UI,则应使用ReportProgress并处理该ProgressReported事件.要从UI获取信息以便在长时间运行的任务中使用,您应该在启动后台任务之前访问它.对于不属于这些情况的特殊情况,可能适合使用Invoke,但其余情况应该是罕见的.
我不太确定你想如何使用这些值,但只是举个例子,你可以在BackgroundWorker线程中轻松地做到这一点:
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;
}));
}
Run Code Online (Sandbox Code Playgroud)
请参阅此答案以了解其他相同的方法(这是针对> = .Net 3.5)
| 归档时间: |
|
| 查看次数: |
13004 次 |
| 最近记录: |