Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#螺纹问题_C#_Multithreading_Backgroundworker - Fatal编程技术网

C#螺纹问题

C#螺纹问题,c#,multithreading,backgroundworker,C#,Multithreading,Backgroundworker,为了处理线程、代理和后台工作人员,我正在组装一些小应用程序,其中一个有点麻烦。 我有一个Windows窗体,有一个文本框、一个按钮和一个richttext。 当我按下按钮时,文本框中的文本被用作实例化类的参数,如下所示: public partial class Form1 : Form { private BackgroundWorker backgroundWorker; public Form1() { InitializeComponent();

为了处理线程、代理和后台工作人员,我正在组装一些小应用程序,其中一个有点麻烦。 我有一个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();            
    }
}
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); });
    }
}
调试时,我遇到一个'textBox1.Lines'抛出了一个类型为“Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessaginException”的异常
关于如何解决这个问题有什么建议吗?

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

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();            
    }
}
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); });
    }
}

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

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

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();            
    }
}
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); });
    }
}

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

主要原因是文本框不属于后台线程

您的UI线程拥有所有UI对象,当按下按钮时,您正在旋转一个后台线程。该后台线程不应有权访问任何UI对象

如果希望使用文本框的值,则需要以另一种方式将其传递给后台线程


主要原因是文本框不属于后台线程

您的UI线程拥有所有UI对象,当按下按钮时,您正在旋转一个后台线程。该后台线程不应有权访问任何UI对象

如果希望使用文本框的值,则需要以另一种方式将其传递给后台线程


只能从主线程本身更新主线程上的控件,除非使用控件的.Invoke方法明确告诉程序可以这样做

From: http://www.albahari.com/threading/part3.aspx
控制。调用


在多线程Windows窗体应用程序中,从创建控件的线程以外的任何线程调用控件的方法或属性是非法的。所有跨线程调用必须使用control.Invoke或control.BeginInvoke方法显式封送到创建控件的线程(通常是主线程)。人们不能依赖自动编组,因为它发生得太晚了——只有当执行深入到非托管代码中时,此时大量的内部.NET代码可能已经在“错误”线程上运行了——这些代码不是线程安全的。

您只能从主线程本身更新主线程上的控件,除非您使用控件的.Invoke方法明确告诉您的程序可以这样做

From: http://www.albahari.com/threading/part3.aspx
控制。调用

在多线程Windows窗体应用程序中,从创建控件的线程以外的任何线程调用控件的方法或属性是非法的。所有跨线程调用必须使用control.Invoke或control.BeginInvoke方法显式封送到创建控件的线程(通常是主线程)。人们不能依赖自动编组,因为它发生得太晚——只有当执行顺利进入非托管代码时,此时大量内部.NET代码可能已经在“错误”线程上运行了——这些代码不是线程安全的