与 backgroundWorker 的死锁
Dead lock with backgroundWorker
我在使用多线程时遇到了一个有趣的时刻。
我有两个线程。在主线程中我创建布局并添加到它的控件,在第二个线程中我创建另一个控件并添加到相同的布局。它工作正常,但第二个线程的工作时间比主线程长一点。所以 main 应该等待第二个 thread.I 用于这个 AutoResetEvent
并得到死锁。下面我描述一下我使用的代码:
private static AutoResetEvent resetEvent = new AutoResetEvent(false);
private BackgroundWorker backgroundAdvancedViewWorker = new BackgroundWorker();
private delegate void ShowViewDelegate();
public void Run()
{
MainGeneralReportForm mainForm = ObjectFactory.GetOrCreateView<IMainGeneralReportForm>();
backgroundSimpleViewWorker.RunWorkerAsync(_mainForm);
GeneralReportFormatView formatView =
ObjectFactory.ShowView<IGeneralReportFormatView>()
resetEvent.WaitOne();
DoSomething(advancedSearchView);
}
private void backgroundAdvancedViewWorker_DoWork(object sender, DoWorkEventArgs e)
{
MainGeneralReportForm mainForm = e.Argument as MainGeneralReportForm;
if (mainForm!= null && mainForm.InvokeRequired)
{
mainForm.BeginInvoke(new ShowViewDelegate(() =>
{
advancedSearchView =
ObjectFactory.ShowView<IGeneralReportAdvancedSearchView>();
resetEvent.Set();
}));
}
}
}
如果主线程不等待第二个线程,应用程序将抛出 NullReferenceException
。
是否存在此问题的任何解决方案或解决方法?
您通过 resetEvent.WaitOne();
阻塞主线程,同时尝试使用 BeginInvoke
将工作项安排回主线程(这确实不能 运行 因为主线程是等待)。
不确定正确的解决方法是什么,但在主线程上阻塞并不是一个真正的选择。
也许表单上的某些 "state" 字段就足够了。或者 运行ning DoSomething(advancedSearchView);
来自 BeginInvoke
回调(而不是 resetEvent.Set();
)。
注意:如果您使用的是 4.5,则可以考虑使用 async
/await
而不是手动穿线。
我在使用多线程时遇到了一个有趣的时刻。
我有两个线程。在主线程中我创建布局并添加到它的控件,在第二个线程中我创建另一个控件并添加到相同的布局。它工作正常,但第二个线程的工作时间比主线程长一点。所以 main 应该等待第二个 thread.I 用于这个 AutoResetEvent
并得到死锁。下面我描述一下我使用的代码:
private static AutoResetEvent resetEvent = new AutoResetEvent(false);
private BackgroundWorker backgroundAdvancedViewWorker = new BackgroundWorker();
private delegate void ShowViewDelegate();
public void Run()
{
MainGeneralReportForm mainForm = ObjectFactory.GetOrCreateView<IMainGeneralReportForm>();
backgroundSimpleViewWorker.RunWorkerAsync(_mainForm);
GeneralReportFormatView formatView =
ObjectFactory.ShowView<IGeneralReportFormatView>()
resetEvent.WaitOne();
DoSomething(advancedSearchView);
}
private void backgroundAdvancedViewWorker_DoWork(object sender, DoWorkEventArgs e)
{
MainGeneralReportForm mainForm = e.Argument as MainGeneralReportForm;
if (mainForm!= null && mainForm.InvokeRequired)
{
mainForm.BeginInvoke(new ShowViewDelegate(() =>
{
advancedSearchView =
ObjectFactory.ShowView<IGeneralReportAdvancedSearchView>();
resetEvent.Set();
}));
}
}
}
如果主线程不等待第二个线程,应用程序将抛出 NullReferenceException
。
是否存在此问题的任何解决方案或解决方法?
您通过 resetEvent.WaitOne();
阻塞主线程,同时尝试使用 BeginInvoke
将工作项安排回主线程(这确实不能 运行 因为主线程是等待)。
不确定正确的解决方法是什么,但在主线程上阻塞并不是一个真正的选择。
也许表单上的某些 "state" 字段就足够了。或者 运行ning DoSomething(advancedSearchView);
来自 BeginInvoke
回调(而不是 resetEvent.Set();
)。
注意:如果您使用的是 4.5,则可以考虑使用 async
/await
而不是手动穿线。