与 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 而不是手动穿线。