C # thread synchronization with multiple threads 2,

Source: Internet
Author: User

C # thread synchronization with multiple threads 2,

In the previous C # multi-thread synchronization 1, we mainly learned to execute basic atomic operations, use Mutex construction, and SemaphoreSlim construction, this article describes how to use AutoResetEvent construction, ManualResetEventSlim construction, and CountDownEvent construction.

4. Use AutoResetEvent to construct

In this section, we will learn how to use the AutoResetEvent construction to send notifications from one thread to another. AutoResetEvent notifies a waiting thread that an event has occurred. The procedure is as follows:

1. Use Visual Studio 2015 to create a new console application.

2. Double-click to open the "Program. cs" file and write the code as follows:

 1 using System; 2 using System.Threading; 3 using static System.Console; 4 using static System.Threading.Thread; 5  6 namespace Recipe04 7 { 8     class Program 9     {10         private static AutoResetEvent workerEvent = new AutoResetEvent(false);11         private static AutoResetEvent mainEvent = new AutoResetEvent(false);12 13         static void Process(int seconds)14         {15             WriteLine("Starting a long running work...");16             Sleep(TimeSpan.FromSeconds(seconds));17             WriteLine("Work is done!");18             workerEvent.Set();19             WriteLine("Waiting for a main thread to complete its work");20             mainEvent.WaitOne();21             WriteLine("Starting second operation...");22             Sleep(TimeSpan.FromSeconds(seconds));23             WriteLine("Work is done!");24             workerEvent.Set();25         }26 27         static void Main(string[] args)28         {29             var t = new Thread(() => Process(10));30             t.Start();31 32             WriteLine("Waiting for another thread to complete work");33             workerEvent.WaitOne();34             WriteLine("First operation is completed!");35             WriteLine("Performing an operation on a main thread");36             Sleep(TimeSpan.FromSeconds(5));37             mainEvent.Set();38             WriteLine("Now running the second operation on a second thread");39             workerEvent.WaitOne();40             WriteLine("Second operation is completed!");41         }42     }43 }

3. Run the console application. The running effect may be different each time, as shown in:

In 10th ~ At Line 11 of the code, we define two AutoResetEvent instances: workerEvent and mainEvent. WorkerEvent is used to send notifications to the main thread from the new thread. mainEvent is used to send notifications to the new thread from the main thread. When calling the AutoResetEvent constructor, we pass a false value to the initialState parameter of the constructor, specifying that the initial status of the AutoResetEvent instance is "stateless ", this means that the thread that calls the "WaitOne" method of the AutoResetEvent instance will be blocked until we call the "Set" method of the AutoResetEvent instance. If we set the value of the initialState parameter in the constructor of the AutoResetEvent class to true, the initial status of the AutoResetEvent instance is "Signal status ", the first thread that calls the "WaitOne" method of the AutoResetEvent instance will be executed immediately, and the status of the AutoResetEvent instance will automatically change to "no signal". At this time, when we call the "WaitOne" method of AutoResetEvent again, we must call the "Set" method of AutoResetEvent in another thread to continue executing the current thread.

At line 1 of code, we created a new thread to execute the "Process" method and start the thread at line 2 of code.

At line 1 of code, we call the workerEvent method of the AutoResetEvent instance to block the main thread. However, in the thread we created at line 2 of code, the "Set" method of the WorkerEvent instance of AutoResetEvent is called. Therefore, the main thread can continue execution. When the code is executed at line 1, we call the "WaitOne" method of mainEvent of the AutoResetEvent instance in the new thread, which causes the new thread to be blocked, however, when the main thread executes the Code in line 37th, we call the "Set" method of mainEvent of the AutoResetEvent instance. Therefore, the new thread can continue to be executed. While the main thread is executing at the second line of code, the main thread is blocked, and the new thread is executing at the second line of code, causing the main thread to continue executing. Therefore, the main thread executes the code to 40th lines, and the console application ends normally.

AutoResetEvent is constructed by kernel-time. Therefore, we recommend that you replace AutoResetEvent with ManualResetEventslim described in the next section.

5. Use ManualResetEventSlim to construct

In this section, we will learn how to use ManualResetEventSlim to construct a more flexible way to send notifications between multiple threads. The procedure is as follows:

1. Use Visual Studio 2015 to create a new console application.

2. Double-click to open the "Program. cs" file and write the code as follows:

 1 using System; 2 using System.Threading; 3 using static System.Console; 4 using static System.Threading.Thread; 5  6 namespace Recipe05 7 { 8     class Program 9     {10         private static ManualResetEventSlim mainEvent = new ManualResetEventSlim(false);11 12         static void TravelThroughGates(string threadName, int seconds)13         {14             WriteLine($"{threadName} falls to sleep");15             Sleep(TimeSpan.FromSeconds(seconds));16             WriteLine($"{threadName} waits for the gates to open!");17             mainEvent.Wait();18             WriteLine($"{threadName} enters the gates!");19         }20         21         static void Main(string[] args)22         {23             var t1 = new Thread(() => TravelThroughGates("Thread 1", 5));24             var t2 = new Thread(() => TravelThroughGates("Thread 2", 6));25             var t3 = new Thread(() => TravelThroughGates("Thread 3", 12));26 27             t1.Start();28             t2.Start();29             t3.Start();30 31             Sleep(TimeSpan.FromSeconds(6));32             WriteLine("The gates are now open!");33             mainEvent.Set();34             Sleep(TimeSpan.FromSeconds(2));35             mainEvent.Reset();36             WriteLine("The gates have been closed!");37             Sleep(TimeSpan.FromSeconds(10));38             WriteLine("The gates are now open for the second time!");39             mainEvent.Set();40             Sleep(TimeSpan.FromSeconds(2));41             WriteLine("The gates have been closed!");42             mainEvent.Reset();43         }44     }45 }

3. Run the console application. The running effect may be different each time, as shown in:

In the code of Row 3, we define a mainEvent of the ManualResetEventSlim type instance and pass the false value to the "initialState" parameter of its constructor, indicates that the initial state of the object is "no signal ".

In 23rd ~ At 25 lines of code, we created three threads t1, t2, and t3. All three threads are used to execute the "TraveThroughGates" method. Within this method, we call the "Wait" method of the mainEvent of the ManualResetEventSlim instance, to block the execution of t1, t2, and t3 threads.

At line 1 of code, we have blocked the main thread for 6 seconds. During these six seconds, both thread t1 and thread t2 are executed to line 2 of code. At this time, both thread t1 and thread t2 are blocked, and wait until the "Set" method of mainEvent is called to continue executing after receiving the signal. After the main thread blocks for 6 seconds, it will execute 33rd lines of code. After this line of code is executed, thread t1 and thread t2 will receive notifications. Therefore, thread t1 and thread t2 will continue to be executed, therefore, all the code is executed. After that, the thread t1 and t2.

Because thread t3 is still blocked when the main thread executes code at line 3 (because of the execution of Line 3 Code, therefore, thread t3 is not affected when the main thread executes code at line 3 and continues to be blocked.

When the main thread executes the code at the second line, thread t3 is still in the blocking status. After the main thread executes 35th lines of code, mainEvent is reset to "stateless ". When the main thread executes to the second line of code, the main thread is blocked for 10 seconds. Within 10 seconds after the main thread is blocked, thread t3 will execute to line 3 of the Code, and the thread t3 will be blocked. The execution can continue only after the notification arrives.

After the main thread is blocked for 10 seconds, it will execute 39th lines of code, resulting in thread t3 continuing to execute. Therefore, it will execute 18th lines of code and thread t3 will end.

After the main thread is blocked for 2 seconds, the mainEvent is reset to "no signal" and the main thread ends.

6. Use CountdownEvent to construct

In this section, we will learn how to use CountdownEvent to construct a thread that will be blocked until a certain number of notifications are sent. The learning procedure is as follows:

1. Use Visual Studio 2015 to create a new console application.

2. Double-click to open the "Program. cs" file and write the code as follows:

 1 using System; 2 using System.Threading; 3 using static System.Console; 4 using static System.Threading.Thread; 5  6 namespace Recipe06 7 { 8     class Program 9     {10         private static CountdownEvent countdown = new CountdownEvent(2);11 12         static void PerformOperation(string message, int seconds)13         {14             Sleep(TimeSpan.FromSeconds(seconds));15             WriteLine(message);16             countdown.Signal();17         }18 19         static void Main(string[] args)20         {21             WriteLine("Starting two operations");22             var t1 = new Thread(() => PerformOperation("Operation 1 is completed", 4));23             var t2 = new Thread(() => PerformOperation("Operation 2 is completed", 8));24 25             t1.Start();26             t2.Start();27             countdown.Wait();28             WriteLine("Both operations have been completed.");29             countdown.Dispose();30         }31     }32 }

3. Run the console application. The running effect is shown in:

In the code of Row 3, we created a CountdownEvent instance countdown and passed the value 2 to the initialCount parameter of the constructor, it indicates that we want to wait until the two notifications are sent and the blocked thread can continue to execute.

In 22nd ~ At the 23th line of code, we created two new threads for executing the "batch moperation" method. In this method, we called the "Signal" method of countdown for sending notifications, and reduce the CurrentCount value of CountdownEvent. When the CurrentCount value is reduced to 0, the blocked thread can continue execution.

At line 1 of code, we call the countdown "Wait" method in the main thread to block the main thread until the system receives the notification and the CurrentCount value is 0, the main thread can continue execution.

Note: If you change 2 of the 10th line of code to 3 and run the program again, the main thread will remain waiting and will not end, because the CurrentCount value is not reduced to 0.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.