与backgroundWorker的死锁

时间:2015-04-21 16:09:07

标签: c# multithreading winforms backgroundworker

在处理多线程时,我遇到了一个有趣的时刻。 我有两个主题。在主线程中我创建布局并添加到它控件,在第二个线程中我创建另一个控件并添加到相同的布局。它工作正常,但第二个线程比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。 是否存在此问题的任何解决方案或解决方法?

1 个答案:

答案 0 :(得分:0)

您通过resetEvent.WaitOne();阻止主线程,同时尝试使用BeginInvoke将工作项安排回主线程(当主线程正在等待时,它确实无法运行)。 / p>

不确定什么是正确的修复,但主线程上的阻塞实际上不是一个选项。

也许一些&#34;州&#34;表格上的字段可能就足够了。或者可以从DoSomething(advancedSearchView);回调(而不是BeginInvoke)运行resetEvent.Set();

注意:如果您使用的是4.5,则可以考虑使用async / await代替手动线程。