跨线程异常 [英] Cross thread exception

查看:113
本文介绍了跨线程异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一阵子问题



这行:

  txtPastes.Text =(字符串)e.UserState; 



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



txtPastes - 文本



GuiUpdate - BackgroundWorker的



lstAllPastes - 字符串列表

 私人无效GuiUpdate_DoWork(对象发件人,DoWorkEventArgs E)
{
,而(真)
{
,而(lstAllPastes.Count == 0);

的for(int i = 0; I< lstAllPastes [0]。长度;我+ +)
{
GuiUpdate.ReportProgress(0,lstAllPastes [0] .Substring(0 , 一世));
Thread.sleep代码(1);
}
lstAllPastes.RemoveAt(0);
}
}

私人无效GuiUpdate_ProgressChanged(对象发件人,ProgressChangedEventArgs E)
{
txtPastes.Text =(字符串)e.UserState;
}

私人无效GuiUpdate_RunWorkerCompleted(对象发件人,RunWorkerCompletedEventArgs E)
{

}


解决方案

您不能更新从非UI线程以外的任何线程UI控件。通常情况下,的BackgroundWorker 会照顾抚养其 ProgressChanged RunWorkerCompleted 正确的UI线程事件。由于不会出现在这里是这种情况,你可以封你的UI更新逻辑的UI使用调用方法线程自己:

  txtPastes.Invoke(新动作(()=> 
{
//此代码是在UI线程上执行。
txtPastes.Text =(字符串)e.UserState;
}));

如果你在WPF,你需要调用调用在控制的调度:

  txtPastes.Dispatcher.Invoke(新动作(()=> 
{
txtPastes.Text =(字符串)e.UserState;
}));



更新:正如托马斯·莱韦斯克和Hans帕桑特已经提到的,你应该调查为什么你的 ProgressChanged 事件不被UI线程上提出的原因。我怀疑是你开始的的BackgroundWorker 在应用程序初始化的生命周期,这可能导致竞争条件和太早可能是的NullReferenceException 如果第一次 ProgressChanged 事件的 txtPastes 文本框被初始化之前提出。


I am having a problem for a while

this line:

txtPastes.Text = (string)e.UserState;

throws a cross thread exception and I didn't find any solution

txtPastes - textbox

GuiUpdate - BackgroundWorker

lstAllPastes - list of string

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

    }

解决方案

You cannot update a UI control from any thread other than the UI thread. Typically, the BackgroundWorker would take care of raising its ProgressChanged and RunWorkerCompleted events correctly on the UI thread. Since that doesn’t appear to be the case here, you could marshal your UI-updating logic to the UI thread yourself by using the Invoke method:

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

If you’re on WPF, you would need to call Invoke on the control’s dispatcher:

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

Update: As Thomas Levesque and Hans Passant have mentioned, you should investigate the reason why your ProgressChanged event is not being raised on the UI thread. My suspicion is that you’re starting the BackgroundWorker too early in the application initialization lifecycle, which could lead to race conditions and possibly a NullReferenceException if the first ProgressChanged event is raised before your txtPastes textbox has been initialized.

这篇关于跨线程异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆