First Let's understanding the Thread and MultiThread and synchronous and asynchronous
Read here
What is Single Thread and MultiThread
Single Thread:
If we have couple of tasks to be worked on and the current system provides a single thread which can work all those, then it takes one by one and process as
Here we can see that we have a thread (Thread 1) and four tasks to be completed. Thread starts processing one by one and completes all. (The order in which tasks will be taken up, does not affect the execution, we can have different algorithm which can define the priorities of tasks)
Multi-Thread:
Here we can see that we have four threads and same number of tasks to complete and each thread start working on that This is ideal scenario but in normal case, we used to have more number of tasks then number of available threads so whichever thread gets free takes up another task. As already said that spawning new thread is not an option every time because it requires system resources like CPU, memory and based on that number of threads should be decided.
Synchronous Single Threaded
Synchronous Multi-Threaded
Asynchronous Single Threaded
Asynchronous Multi-Threaded
What is Synchronous and Asynchronous
Synchronous
1. You are in a queue to get a movie ticket. You cannot get one until everybody in front of you gets one and the same applies to the people queued behind you
2. Ammunition in the gun: shot every ammunition one by one
Asynchronous
Example:
1. You are in restaurant with many other people. You order your food. Other people can also order their food. They don’t have to wait for your food to be cooked and served to you before they can order. In the kitchen, workers are continuously cooking, serving and taking orders. People will get their food servered as soon as it is cooked
2. About car traffic: the car can pass another car, no need to waiting the before car
---------------------------------------------
Many people are taught that multi-Threading and asynchrony are the same thing, but they are not.
An analogy usually helps/ You are cooking in a restaurant. An order comes in for eggs and toast.
Synchronous:: you cook the eggs, then you cook the toast
Asynchronous, single threaded: you start the eggs cooking and set a timer. You start the toast cooking, and set a timer. While they are both cooking, you clean the kitchen. When the timers go off you take the eggs off the heat and the toast out of the toaster and serve them.
Asynchronous, multi-Threaded: you hire two more cooks, one to cook eggs and one to cook toast. Now you have the problem of coordinating the cooks so that they do not conflict with each other in the kitchen when sharing resources. And you have to pay them.
Now does it make sense that multi-Threading is only one kind of asynchrony?
Threading is about workers; Asynchrony is about tasks.
Threading is about workers; Asynchrony is about tasks.
In multi-Threaded workflows you assign tasks to workers.
In asynchronous single-Threaded workflows you have a graph of tasks where some tasks depend on the results of others; as each task completes it invokes the code that schedules the next task that can run, given the results of the just-completed task. But you (hopefully) only need one worker to perform all the tasks, not one worker per task
Resource contention
- when running a application, the main is created, that's call main-thread. if this have many thread doing the multi-task and the thread need use the resource from the main thread, if you try to access resource from the main thread, you can get resource contention problem
- The Invoke is appeared at this time to help you lock the resource guaranteed the thread-safe and don't make the problem is crashed by resource contention!
- Khi chạy một ứng dụng, có một thread được tạo ra để chạy hàm Main(). Đó là thread chính (main-thread). Nếu chương trình có nhiều thread thực hiện các tác vụ xử lý khác và các thread này cần sử dụng tài nguyên từ thread chính thì bạn phải cần tới Invoke. Thực ra, bạn có thể đặt thuộc tính CheckForIllegalCrossThreadCalls = false; cho form (hoặc control) và sử dụng các tài nguyên từ thread khác một cách thoải mái. Nhưng như vậy, chương trình sẽ rơi vào trạng thái ko an toàn (unsafe) và sẽ bị crash bất cứ lúc nào khi các thread tranh chấp tài nguyên với nhau.
- C# cung cấp 1 giải pháp an toàn hơn đó là Invoke. Khi bạn gọi phương thức này của một form (hoặc control) từ 1 thread khác, form (control) đó sẽ bị lock, chỉ cho phép thread đã gọi nó truy cập. Khi thread này hoàn thành tác vụ của nó, form (control) lại được giải phóng cho thread khác gọi. Như vậy, các thread sẽ được đồng bộ với nhau và chương trình của bạn sẽ ko bị crash. Đó gọi là thread-safe.
- Có những control ko yêu cầu Invoke để thực hiện thread-safe. Nghĩa là nó có thể được truy cập một cách trực tiếp không qua Invoke. Thuộc tính InvokeRequired sẽ cho biết một control có yêu cầu Invoke khi gọi hay không?
BeginInvoke and Invoke
BeginInvoke() will schedule the asynchronous action on the GUI thread. When the asynchronous action is scheduled, your code continues. Some time later (you don't know exactly when) your asynchronous action will be executedInvoke() will execute your asynchronous action (on the GUI thread) and wait until your action has completed. -> easy get deadlock but safe than BeginInvoke
Look at the below example:
Source code
Main.csprivate bool isProcessRunning = false;
private void Demo(object sender, EventArgs e)
{
listBox1.Items.Clear();
// If a process is already running, warn the user and cancel the operation
if (isProcessRunning)
{
MessageBox.Show("A process is already running.");
return;
}
// Initialize the thread that will handle the background process
Thread backgroundThread = new Thread(new ThreadStart(() => CallingThread()));
// Start the background process thread
backgroundThread.Start();
}
1st Example:
single code:listBox1.Invoke(new Action(() => listBox1.Items.Add(lst[i])));
multi code: use { and }
listBox1.BeginInvoke(new Action(() =>
{
listBox1.Items.Add(lst[i]))
});
We use Invoke in this case because we want to wait until the user action has completed.
// Developer: zidane / VịLH (huuvi168@gmail.com)
// Last modified: 2016-07-07
private void CallingThread()
{
toolStripProgressBar.ProgressBar.Invoke(new Action(() =>
toolStripProgressBar.Style = ProgressBarStyle.Marquee));
toolStripStatusLabel.Text = "Waiting for task ...";
// Set the flag that indicates if a process is currently running
isProcessRunning = true;
clsDBConnect clsDB = new clsDBConnect();
List<string> lst = clsDB.SelectQueryString();
// Thread.sleep(100); // remember set Thread.Sleep(1000) here
for (int i = 0; i < lst.Count; i++)
{
if (listBox1.InvokeRequired)
listBox1.Invoke(new Action(() => listBox1.Items.Add(lst[i])));
}
// Show a dialog box that confirms the process has completed
toolStripStatusLabel.Text = "Done";
// Reset the progress bar's value if it is still valid to do so
toolStripProgressBar.ProgressBar.Invoke(new Action(() =>
toolStripProgressBar.Style = ProgressBarStyle.Continuous));
// Reset the flag that indicates if a process is currently running
isProcessRunning = false;
}
2nd Example:
listBox1.BeginInvoke(new Action(() => listBox1.Items.Add(lst[i])));Shouldn't use beginInvoke in this case, because it will crashed your program.
private void CallingThread()
{
toolStripProgressBar.ProgressBar.Invoke(new Action(() =>
toolStripProgressBar.Style = ProgressBarStyle.Marquee));
toolStripStatusLabel.Text = "Waiting for task ...";
// Set the flag that indicates if a process is currently running
isProcessRunning = true;
clsDBConnect clsDB = new clsDBConnect();
List<string> lst = clsDB.SelectQueryString();
for (int i = 0; i < lst.Count; i++)
{
if (listBox1.InvokeRequired)
listBox1.BeginInvoke(new Action(() => listBox1.Items.Add(lst[i])));
}
// Show a dialog box that confirms the process has completed
toolStripStatusLabel.Text = "Done";
// Reset the progress bar's value if it is still valid to do so
toolStripProgressBar.ProgressBar.Invoke(new Action(() =>
toolStripProgressBar.Style = ProgressBarStyle.Continuous));
// Reset the flag that indicates if a process is currently running
isProcessRunning = false;
}
Relative topic
https://learn-tech-tips.blogspot.com/2015/11/how-to-fix-cross-thread-problem-CSharp.html
If you have any feedback, leave your comment, we can discuss about it!
Have a nice day!
Zidane
https://learn-tech-tips.blogspot.com/