SoFunction
Updated on 2025-03-01

C# method to implement the interaction between form and child thread

This example briefly describes the method of C# to implement communication between forms and child threads, which has certain reference value for beginners in C#. The specific methods are as follows:

Generally speaking, the UI on the form does not allow child threads (or other UI threads that do not create controls) to be controlled by default (this is allowed below NET 2.0, but considering security issues, this function has been prohibited from using it since 2.0, unless Form's CheckForIllegalCrossThreadCalls=true, this is not recommended).

So how to implement the interaction between C# form and child thread? The specific methods are as follows:

1. Use Invoke or BeginInvoke method:

Use a thread and call the Invoke or BeginInvoke method:

public partial class Form1 : Form
{
public void Processing(int num)
{
int answer = 2;
Task t = new Task(() =>
{
for (int i = 3; i <= num; i++)
{
answer *= i;
}
(new MethodInvoker(() => { (3000); ("Finished!") }));
("OK");
});
();
}
public Form1()
{
InitializeComponent();

}
private void button1_Click(object sender, EventArgs e)
{
("First!");
Processing(10);
}
}

It is worth noting here:
1) BeginInvoke: The "asynchronous" here is not for the UI thread, but when the Control's BeginInvoke is called in a child thread, the code behind BeginInvoke (the "Finished" box pops up) in the child thread will be executed first, and then the Label will be assigned until the delegate method in BeginInvoke is fully executed. If changed to Invoke, then "OK" will never be executed after the Invoke delegate code is completely executed.
So BeginInvoke=Invoke (in the main UI thread, it is not recommended to call it like this directly in the main thread)

2. Thread synchronization SynchronizedContext:

public partial class Form1 : Form
{
public void Processing(int num,SynchronizationContext context)
{
int answer = 2;
Task t = new Task(() =>
{
for (int i = 3; i <= num; i++)
{
answer *= i;
}
(context);
((obj) => { (3000); ("Finished"); }, null);
("Last");
});
();
}
public Form1()
{
InitializeComponent();

}
private void button1_Click(object sender, EventArgs e)
{
("First!");
Processing(10,);
}
}

Similar to BeginInvoke and Invoke, you need to pay attention to:

1) SynchronizationContext: Only in the UI form thread will be automatically initialized (the current form is in the button1_Click event). To interact with other threads, it must be implemented through new SynchronizationContext()).
2) The Post method is equivalent to the function of BeginInvoke, and Send is equivalent to the function of Invoke.

If you carefully experiment with the code, you will find that no matter what the situation, the "Finished" box pops up, always "fake death" on the interface for 3 seconds. Yes, it proves that the above four methods are executed on the UI thread (it is just to send information to the form message pump synchronously or asynchronously). Therefore, you should "process all the data in the child thread at once (get the result before Invoke, BeginInvoke, Send or Post, write the code), and then send a notification to the form at once and update the interface).

Also note:

Any delegate also has a BeginInvoke method, which is truly asynchronous. Once Invoke is bound to open a thread to execute.