在RunWorkerCompleted WinForms .net中运行BackGroundWorker

时间:2012-02-04 00:22:13

标签: .net winforms backgroundworker

我想知道在RunWorkerComplete1中运行A Backgrounworker2是否“危险”如下:

public void backgroundworker1RunComplete (Object sender , RunworkerCompleteEvent e)
{
    Backgroundworker2.runAsync();
}

可能是任何僵局,各种问题等? 也许我只有两种选择:

在RunComplete1中运行Backgrounworker2异步 使用ManualReset事件当我在WorkerComplete1中输入BackGroundWorker DoWork1和i Set()时我重置

1号)

  private void BackgroundWorker1RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  {
       backgroundWorker2.RunAsync();
  }

2号)

 private void BackgroundWorker1RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  {
       manualReset.Set();  
  }

 private void BackGrounWorker2DoWork(Object sender , DoWorkEventArgs e)
 {
   manualReset.WaitOne();
  //Do Stuff
 }

1 个答案:

答案 0 :(得分:0)

启动后台线程的后台线程(这基本上就是你在这里做的)是完全有效的。我已经看到并构建了依赖于此的算法,甚至还有一个同一个BGW用不同的命令重启自己,这个命令触发了不同的逻辑(不是我的设计,我遇到了它的问题,但它得到了这份工作完成)。

你只需要确保你知道你(和你的后台线程)正在做什么,以及他们不应该做什么:

  • 确保没有可能的死锁,两个BGW都在等待另一个完成。在这种情况下,BGW1启动BGW2(尚未运行)并且似乎在此之后完成,所以这不太可能。但是,如果两者同时运行并等待另一个在任何给定点完成,或者获取两个BGW所需的不同对象的锁定,则可能存在问题。

  • 不要尝试直接从其BGW上的表单上获取或设置属性/字段值或调用方法。如果必须这样做,请使用Control.Invoke或Control.BeginInvoke。您可以通过简单的扩展方法避免知道差异。

这是扩展方法(似乎是格式化程序中的一个错误;不能将代码块放在列表中间):

public static void InvokeIfNecessary(this Control ctrl, Action action)
{
    if(ctrl.InvokeRequired)
    {
       ctrl.Invoke((MethodInvoker)action);
       return;
    }

    action();
}

您可以在此处创建其他变体来获取或返回值,但是通过明智地使用外部闭包,您几乎可以使用它。

  • 关闭包含表格时,不要忘记等待或取消BGW。这可能需要您构建doWork方法(以及它直接调用的长时间运行的方法),以便在从外部发出信号时知道是否以及何时退出。