我想知道在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
}
答案 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();
}
您可以在此处创建其他变体来获取或返回值,但是通过明智地使用外部闭包,您几乎可以使用它。