跨线程异常

时间:2012-02-18 16:11:49

标签: c# winforms

我有一段时间有问题

这一行:

txtPastes.Text = (string)e.UserState;

抛出一个跨线程异常,我没有找到任何解决方案

txtPastes - 文本框

GuiUpdate - BackgroundWorker

lstAllPastes - 字符串列表

    private void GuiUpdate_DoWork(object sender, DoWorkEventArgs e)
    {
        while (true)
        {
            while (lstAllPastes.Count == 0) ;

            for (int i = 0; i < lstAllPastes[0].Length; i++)
            {
                GuiUpdate.ReportProgress(0, lstAllPastes[0].Substring(0, i));
                Thread.Sleep(1);
            }
            lstAllPastes.RemoveAt(0);
        }
    }

    private void GuiUpdate_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        txtPastes.Text = (string)e.UserState;
    }

    private void GuiUpdate_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {

    }

4 个答案:

答案 0 :(得分:5)

您无法从UI线程以外的任何线程更新UI控件。通常,BackgroundWorker会在UI线程上正确地提升其ProgressChangedRunWorkerCompleted事件。由于此处似乎并非如此,您可以使用Invoke方法自行将UI更新逻辑封送到UI线程:

txtPastes.Invoke(new Action(() => 
{ 
    // This code is executed on the UI thread.
    txtPastes.Text = (string)e.UserState; 
}));

如果您使用WPF,则需要在控件的调度程序上调用Invoke

txtPastes.Dispatcher.Invoke(new Action(() => 
{ 
    txtPastes.Text = (string)e.UserState; 
}));

更新:正如Thomas Levesque和Hans Passant所提到的,您应该调查在UI线程上没有引发ProgressChanged事件的原因。我怀疑你是否在应用程序初始化生命周期中过早地启动BackgroundWorker,这可能会导致竞争条件,如果在{NullReferenceException之前引发第一个ProgressChanged事件,可能会txtPastes {{1}} {1}}文本框已初始化。

答案 1 :(得分:2)

嗯,这当然应该是有效的。您的代码段中不会显示此异常的原因。重要的是启动BackgroundWorker的位置和时间。它的RunWorkerAsync()方法使用SynchronizationContext.Current属性来确定执行ProgressChanged事件处理程序所需的线程。

以下情况可能会出错:

  • 在Application.Run()调用之前,你太早启动了BGW。 Winforms或WPF还没有机会安装自己的同步提供程序。
  • 您在工作线程中调用了BGW的RunWorkerAsync()方法。只支持封送到UI线程,消息循环是使另一个线程上的代码运行的关键因素。
  • 具有txtPastes控件的表单是在另一个线程上创建的。随着BGW在UI线程上启动仍然是一个线程不匹配
  • 在另一个线程上调用了表单的Show()方法。这会在错误的线程上创建本机Windows窗口。

答案 2 :(得分:1)

确保从UI线程启动BackgroundWorker;如果这样做,将在该线程上引发ProgressChanged事件,并且不会发生异常。

答案 3 :(得分:0)

如果您想更新GUI,例如TextBox,您应该阅读本文:

Update GUI from another thread