C#关于调用、调用要求和;多线程

C#关于调用、调用要求和;多线程,c#,multithreading,invoke,invokerequired,C#,Multithreading,Invoke,Invokerequired,我有两个表单在不同的线程上运行。Form2将生成一个字符串,将其发送回form1并更新form1中的richtextbox。我从我朋友那里得到了密码,但我一部分都不懂 请你向我解释一下为什么我们需要这个条件: if (this.f1_rtb_01.InvokeRequired) { } 下面两行是做什么的 SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); 完整代码

我有两个表单在不同的线程上运行。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();            
    }
}
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows.Forms;
使用系统线程;
命名空间传递Data2Forms
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
公共字符串stru1;
私人作废通知单表格2()
{
对于(int i=0;i<10;i++)
{
Form2 inst_Form2=新Form2();
inst_form2.ShowDialog();
字符串结果=inst_form2.SelectedString;
这个.SetText(结果);
}
}
委托无效SetTextCallback(字符串文本);
私有void SetText(字符串文本)
{
如果(此.f1\u rtb\u 01.invokererequired)
{
SetTextCallback d=新的SetTextCallback(SetText);
调用(d,新对象[]{text});
}
其他的
{
如果(文本!=“”)
{
this.f1_rtb_01.AppendText(text+Environment.NewLine);
}
其他的
{
this.f1_rtb_01.AppendText(“N/A”+Environment.NewLine);
}
}
}
私有无效f1但单击01(对象发送者,事件参数e)
{
线程额外线程线程01=新线程(()=>调用表单线程2());
额外螺纹_01.Start();
}
}
}

每个表单在不同的线程上运行。让我们称它们为thread1和thread2。由于要从thread1更新thread2上的某些内容,因此需要让这两个线程相互通信。这就是调用的工作


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

每个表单在不同的线程上运行。让我们称它们为thread1和thread2。由于要从thread1更新thread2上的某些内容,因此需要让这两个线程相互通信。这就是调用的工作

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

这部分:

SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
使当前窗体调用
SetTextCallback
委托的实例,将变量
text
作为参数传递。委托实例指向
SetText()
方法,由于调用
this.Invoke()
,该方法将在与表单相同的线程上执行

调用用于将代码的执行从后台线程移动到窗体/控件的线程,从而使执行线程安全

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

if (this.f1_rtb_01.InvokeRequired)
如果不需要调用,则意味着代码已在窗体或控件的线程上运行,如果尝试调用,将引发异常。

此部分:

SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
使当前窗体调用
SetTextCallback
委托的实例,将变量
text
作为参数传递。委托实例指向
SetText()
方法,由于调用
this.Invoke()
,该方法将在与表单相同的线程上执行

调用用于将代码的执行从后台线程移动到窗体/控件的线程,从而使执行线程安全

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

if (this.f1_rtb_01.InvokeRequired)

如果不需要调用,则表示代码已在窗体或控件的线程上运行,如果尝试调用,将引发异常。

为什么要在两个线程上运行两个窗体?为什么要在两个线程上运行两个窗体?