C#关于Invoke,Invokerequired&的问题多线程

时间:2016-05-15 05:35:38

标签: c# multithreading invoke invokerequired

我有2个表单在不同的线程上运行。 Form2将生成一个字符串,将其发送回form1并更新form1中的richtextbox。我从朋友那里得到了代码,但我不理解其中的一部分。

请你解释一下为什么我们需要这个条件:

if (this.f1_rtb_01.InvokeRequired) { }

以下两行有什么作用?

SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });

完整代码表格1:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace PassingData2Forms
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    public string str_1;

    private void call_form_2()
    {
        for (int i = 0; i < 10; i++)
        {
            Form2 inst_form2 = new Form2();
            inst_form2.ShowDialog();

            string result = inst_form2.SelectedString;
            this.SetText(result);
        }
    }

    delegate void SetTextCallback(string text);

    private void SetText(string text)
    {
        if (this.f1_rtb_01.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            if (text != "")
            {
                this.f1_rtb_01.AppendText(text + Environment.NewLine);
            }
            else
            {
                this.f1_rtb_01.AppendText("N/A" + Environment.NewLine);
            }
        }
    }

    private void f1_but_01_Click(object sender, EventArgs e)
    {
        Thread extra_thread_01 = new Thread(() => call_form_2());
        extra_thread_01.Start();            
    }
}
}

2 个答案:

答案 0 :(得分:1)

每个表单都在不同的线程上运行。让我们称它们为thread1和thread2。由于您想要从thread1更新thread2上的内容,您需要让这两个线程相互通信。这是invoke的工作

条件是检查是否需要调用。如果要更新thread1上的thread1中的字符串,则不需要调用,否则不需要调用。

答案 1 :(得分:1)

这部分:

SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });

导致当前表单调用SetTextCallback委托的实例,并将变量text作为参数传递。委托实例指向SetText()方法,由于调用this.Invoke(),该方法将在与表单相同的线程上执行。

调用用于将代码的执行从后台线程移动到表单的/控制线程,从而使执行线程安全。

这部分仅用于检查是否需要调用:

if (this.f1_rtb_01.InvokeRequired)

如果您不需要调用,这意味着代码已经在表单或控件的线程上运行,并且如果您尝试调用则会抛出异常。