Today I'll show you how to fix cross-thread problem with the second way. This way is used with Invoke and BeginInvoke API. What is Invoke and BeginInvoke? let's read below topics
First Let's understanding the synchronous and asynchronous read here
Example:
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
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
- 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?
Invoke() 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:
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.
Shouldn't use beginInvoke in this case, because it will crashed your program.
Relative topic
http://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/
First Let's understanding the synchronous and asynchronous read here
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
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
http://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/
Did you know that you can make money by locking selected sections of your blog / site?
ReplyDeleteAll you need to do is to join AdscendMedia and use their Content Locking plugin.