在处理多线程时,我遇到了一个有趣的时刻。
我有两个主题。在主线程中我创建布局并添加到它控件,在第二个线程中我创建另一个控件并添加到相同的布局。它工作正常,但第二个线程比main更长。所以main应该等待第二个线程。我使用这个AutoResetEvent
并获得了DeadLock。下面我描述我使用的代码:
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
。
是否存在此问题的任何解决方案或解决方法?
答案 0 :(得分:0)
您通过resetEvent.WaitOne();
阻止主线程,同时尝试使用BeginInvoke
将工作项安排回主线程(当主线程正在等待时,它确实无法运行)。 / p>
不确定什么是正确的修复,但主线程上的阻塞实际上不是一个选项。
也许一些&#34;州&#34;表格上的字段可能就足够了。或者可以从DoSomething(advancedSearchView);
回调(而不是BeginInvoke
)运行resetEvent.Set();
。
注意:如果您使用的是4.5,则可以考虑使用async
/ await
代替手动线程。