Background
Break News
How to add local font to Tailwind Css and NextJS? - Tutorial Design Pattern? - Blockchain Technology, How to create own Bitcoin virtual currency - Zustand mordern management state - Design Pattern - Flyweight Pattern? - Docker Full training Topic

[Tips] How to fix Cross-thread problem with C# control (2/2) [Updated 2017-01-20]

Wednesday, 3 August 2016
|
Read: Completed in minutes

[Tips] How to fix Cross-thread problem with C# control (2/2) [Updated 2017-01-20]

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 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

What is Single Thread and MultiThread


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:

What is Single Thread and MultiThread


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

Synchrouous and Asynchronous

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

Asynchronous


Synchrouous and 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.
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 executed

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:

Source code

Main.cs

private 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/


🙇🏼🙇🏼 We Appreciate Your Comments and Suggestions - Webzone, all things Tech Tips web development
Popular Webzone Tech Tips topic maybe you will be like it - by Webzone Tech Tips - Zidane
As a student, I found Blogspot very useful when I joined in 2014. I have been a developer for years . To give back and share what I learned, I started Webzone, a blog with tech tips. You can also search for tech tips zidane on Google and find my helpful posts. Love you all,

I am glad you visited my blog. I hope you find it useful for learning tech tips and webzone tricks. If you have any technical issues, feel free to browse my posts and see if they can help you solve them. You can also leave a comment or contact me if you need more assistance. Here is my blog address: https://learn-tech-tips.blogspot.com.

My blog where I share my passion for web development, webzone design, and tech tips. You will find tutorials on how to build websites from scratch, using hot trends frameworks like nestjs, nextjs, cakephp, devops, docker, and more. You will also learn how to fix common bugs on development, like a mini stackoverflow. Plus, you will discover how to easily learn programming languages such as PHP (CAKEPHP, LARAVEL), C#, C++, Web(HTML, CSS, javascript), and other useful things like Office (Excel, Photoshop). I hope you enjoy my blog and find it helpful for your projects. :)

Thanks and Best Regards!
Follow me on Tiktok @learntechtips and send me a direct message. I will be happy to chat with you.
Webzone - Zidane (huuvi168@gmail.com)
I'm developer, I like code, I like to learn new technology and want to be friend with people for learn each other
I'm a developer who loves coding, learning new technologies, and making friends with people who share the same passion. I have been a full stack developer since 2015, with more than years of experience in web development.
Copyright @2022(November) Version 1.0.0 - By Webzone, all things Tech Tips for Web Development Zidane
https://learn-tech-tips.blogspot.com