跨线程异常

mar*_*375 0 c# winforms

我有一段时间有问题

这一行:

txtPastes.Text = (string)e.UserState;
Run Code Online (Sandbox Code Playgroud)

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

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)
    {

    }
Run Code Online (Sandbox Code Playgroud)

Dou*_*las 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; 
}));
Run Code Online (Sandbox Code Playgroud)

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

txtPastes.Dispatcher.Invoke(new Action(() => 
{ 
    txtPastes.Text = (string)e.UserState; 
}));
Run Code Online (Sandbox Code Playgroud)

更新:正如Thomas Levesque和Hans Passant所提到的,你应该调查你的ProgressChanged事件没有在UI线程上被提出的原因.我怀疑你是否BackgroundWorker在应用程序初始化生命周期中起得太早,这可能会导致竞争条件,并且可能会在文本框初始化之前引发NullReferenceException第一个ProgressChanged事件txtPastes.