I have 2 forms running on different threads. Form2 will generate a string, send it back to form1 and update the richtextbox in form1. I got the code from my friend but I don't understand a part of it.
Could you please explain to me why do we need the condition:
if (this.f1_rtb_01.InvokeRequired) { }
And what do 2 lines below do?
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
Full Code Form1:
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();
}
}
}
This part:
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
causes the current form to invoke an instance of the SetTextCallback
delegate, passing the variable text
as a parameter. The delegate instance points to the SetText()
method, which will, due to calling this.Invoke()
, be executed on the same thread as the form.
Invocation is used to move the execution of code from a background thread to a form's/control's thread, thus making the execution thread-safe.
This part is just for checking if you are required to invoke:
if (this.f1_rtb_01.InvokeRequired)
If you aren't required to invoke that means that the code already runs on the form's or control's thread, and will throw an exception if you try to invoke.