C#线程问题

Oxy*_*ron 0 c# multithreading backgroundworker

为了与线程,代表和后台工作者一起玩,我正在整理一些小应用程序,我对其中一个有点麻烦.我有一个Windows表单,带有文本框,按钮和richttext.当我按下按钮时,文本框中的文本被用作实例化类的参数,如下所示:

public partial class Form1 : Form
{
    private BackgroundWorker backgroundWorker;

    public Form1()
    {
        InitializeComponent();            
    }

    private void button1_Click(object sender, EventArgs e)
    {   
        backgroundWorker = new BackgroundWorker();
        backgroundWorker.DoWork += new DoWorkEventHandler(worker_DoWork);
        backgroundWorker.RunWorkerAsync();
    }

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        new Thread((ThreadStart)delegate()
        {
            this.BeginInvoke((ThreadStart)delegate()
            {
                foreach (string line in textBox1.Lines)
                {  
                    Dig digger = new Dig(line, textBox1.Text);
                    digger.DomainChecked += new Dig.DomainCheckedHandler(OnUpdateTicker);

                    string response = digger.GetAllInfo();

                    richTextBox1.AppendText(response);
                    Application.DoEvents();
                }
            });
        }).Start();
    }

    void OnUpdateTicker(string msg)
    {
        new Thread((ThreadStart)delegate()
        {
            this.BeginInvoke((ThreadStart)delegate()
            {
                label4.Text = msg;
                Application.DoEvents();
            });
        }).Start();            
    }
}
Run Code Online (Sandbox Code Playgroud)

调试时我遇到'textBox1.Lines'抛出类型'Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException'的异常 有关如何解决此问题任何提示?

Fre*_*örk 5

首先,不需要在里面创建新线程DoWork; 整体思路与BackgroundWorkerDoWork是在一个单独的线程中执行.其次,由于DoWork在单独的线程上执行,并且只能在UI线程上修改UI控件,因此需要正确调用这些更新.因此,重写版本worker_DoWork可能如下所示:

void worker_DoWork(object sender, DoWorkEventArgs e)
{
    foreach (string line in textBox1.Lines)
    {  
        Dig digger = new Dig(line, textBox1.Text);
        digger.DomainChecked += new Dig.DomainCheckedHandler(OnUpdateTicker);
        string response = digger.GetAllInfo();
        richTextBox1.Invoke((Action) delegate { richTextBox1.AppendText(response); });
    }
}
Run Code Online (Sandbox Code Playgroud)

注意代码如何不显式生成任何新线程,以及如何通过AppendText调用完成方法Control.Invoke调用,强制它在UI线程上执行.