The use of lightweight manual reset events for C # parallel programming

Source: Internet
Author: User

Directory (?) [-]

    1. Simple Introduction
    2. Use timeouts and cancellations
    3. Synchronization across a process or AppDomain
Simple Introduction

If you expect the operation to wait for a very short time, consider using a lightweight manual reset event, ManualResetEventSlim. It can emit signals and wait for events. From the name and use of the way, it is mainly to provide people-oriented operation, in the process based on the human understanding of the program is very familiar with the process of human control of the entire synchronization.

ManualResetEventSlim provides 3 common methods and 3 read-only properties.

constructor function:

    • ManualResetEventSlim (): Initializes a new instance of the ManualResetEventSlim class with a non-signaled initial state.
    • ManualResetEventSlim (Boolean): Class with a Boolean value that indicates whether the initial state is set to signaled.
      A new instance of the ManualResetEventSlim class.
    • ManualResetEventSlim (Boolean, Int32): Initializes a new instance of the ManualResetEventSlim class with a Boolean value that indicates whether the initial state is set to signaled and the specified spin count.

Method:

    • Reset: Set event to False (cancel setting/Cancel signal)
    • Set: Sets the event to true (set/signal), and if a task is waiting, it will get the signal and unblock it.
    • Wait: Blocks the current task or thread until another thread sends a signal.

Property:

    • IsSet: A bool value that indicates whether the event is set.
    • Spincount: Number of spins to be performed before entering the kernel wait.
    • WaitHandle: Provides access to the operating system object WaitHandle. This object allows you to wait for exclusive access to the shared resource.

Example of a program: In this example, ManualResetEventSlim is used, which makes task1,2,3 a sequential operation.

Using System;Using System.Text;Using System.Threading;Using System.threading.tasks;namespace sample5_7_manualreseteventslim{class Program {PrivateStaticint _tasknum =3;PrivateStatic task[] _tasks;PrivateStatic StringBuilder _strblder;PrivateConstint run_loop =10;PrivateStatic ManualResetEventSlim m_worker2event;PrivateStatic ManualResetEventSlim m_worker3event;PrivateStaticvoidWORK1 (int TaskID) {int i =0;String log ="";while (I < run_loop) {log = String.Format ("Time: {0} Task: #{1} Value: {2} =====\n", DateTime.Now.TimeOfDay, TaskID, i); i++;try {_strblder.append (log);}finally {M_worker2event.set ();}} }PrivateStaticvoidWORK2 (int TaskID) {int i =0;String log =""; M_worker2event.wait ();while ((I < Run_loop) && (m_worker2event.isset)) {log = String.Format ("Time: {0} Task: #{1} Value: {2} *****\n", DateTime.Now.TimeOfDay, TaskID, i); i++;try {_strblder.append (log);}finally {M_worker3event.set ();}} }PrivateStaticvoidWORK3 (int TaskID) {int i =0;String log =""; M_worker3event.wait ();while ((I < Run_loop) && (m_worker3event.isset)) {log = String.Format ("Time: {0} Task: #{1} Value: {2} ~~~~~\n", DateTime.Now.TimeOfDay, TaskID, i); i++;try {_strblder.append (log);}Finally {}}}Staticvoid Main (String[] args) {_tasks =New Task[_tasknum]; _strblder =New StringBuilder (); M_worker2event =New ManualResetEventSlim (False100); M_worker3event =New ManualResetEventSlim (False100); _tasks[0] = Task.Factory.StartNew (num) + = {var TaskID = (int) num; Work1 (TaskID); },0); _tasks[1] = Task.Factory.StartNew (num) + = {var TaskID = (int) num; WORK2 (TaskID); },1); _tasks[2] = Task.Factory.StartNew (num) + = {var TaskID = (int) num; Work3 (TaskID); }, 2); var finaltask = Task.Factory.ContinueWhenAll (_tasks, (Tasks) = {Task.waitall (_tasks); Console.WriteLine ( "=========================================================="); Console.WriteLine ( "All Phase is completed"); Console.WriteLine ( "=========================================================="); Console.WriteLine (_strblder); }); try {finaltask.wait ();} catch (AggregateException aex) {Console.WriteLine ( "Task Failed and Canceled "+ AEX. ToString ()); } finally {m_worker2event.dispose (); M_worker3event.dispose ();} Console.ReadLine (); } }}
Use timeouts and cancellations

The timeout mechanism is necessary for the synchronization of tasks, which also provides a way for users to set timeouts.
manualreseteventsilm.wait (int time_out);

Example of the program: In this example, Task 1 waits 5 seconds after setting the event, but the task 2,3 time-out is 2 seconds.

Using System;Using System.Text;Using System.Threading;Using System.threading.tasks;namespace sample5_7_manualreseteventslim{class Program {PrivateStaticint _tasknum =3;PrivateStatic task[] _tasks;PrivateStatic StringBuilder _strblder;PrivateConstint run_loop =10;PrivateStatic ManualResetEventSlim m_worker2event;PrivateStatic ManualResetEventSlim m_worker3event;PrivateStaticvoidWORK1 (int TaskID) {int i =0;String log ="";while (I < run_loop) {log = String.Format ("Time: {0} Task: #{1} Value: {2} =====\n", DateTime.Now.TimeOfDay, TaskID, i); i++;try {_strblder.append (log);}finally {System.Threading.Thread.Sleep (5000); M_worker2event.set (); } } }PrivateStaticvoidWORK2 (int TaskID) {int i =0;String log ="";if (!m_worker2event.wait () {Console.WriteLine ("Task 2 wait for event time out!!");Return }while ((I < Run_loop) && (m_worker2event.isset)) {log = String.Format ("Time: {0} Task: #{1} Value: {2} *****\n", DateTime.Now.TimeOfDay, TaskID, i); i++;try {_strblder.append (log);}finally {M_worker3event.set ();}} }PrivateStaticvoidWORK3 (int TaskID) {int i =0;String log ="";if (!m_worker3event.wait () {Console.WriteLine ("Task 3 wait for event time out!!");Return }while ((I < Run_loop) && (m_worker3event.isset)) {log = String.Format ("Time: {0} Task: #{1} Value: {2} ~~~~~\n", DateTime.Now.TimeOfDay, TaskID, i); i++;try {_strblder.append (log);}Finally {}}}Staticvoid Main (String[] args) {_tasks =New Task[_tasknum]; _strblder =New StringBuilder (); M_worker2event =New ManualResetEventSlim (False100); M_worker3event =New ManualResetEventSlim (False100); _tasks[0] = Task.Factory.StartNew (num) + = {var TaskID = (int) num; Work1 (TaskID); },0); _tasks[1] = Task.Factory.StartNew (num) + = {var TaskID = (int) num; WORK2 (TaskID); },1); _tasks[2] = Task.Factory.StartNew (num) + = {var TaskID = (int) num; Work3 (TaskID); }, 2); var finaltask = Task.Factory.ContinueWhenAll (_tasks, (Tasks) = {Task.waitall (_tasks); Console.WriteLine ( "=========================================================="); Console.WriteLine ( "All Phase is completed"); Console.WriteLine ( "=========================================================="); Console.WriteLine (_strblder); }); try {finaltask.wait ();} catch (AggregateException aex) {Console.WriteLine ( "Task Failed and Canceled "+ AEX. ToString ()); } finally {m_worker2event.dispose (); M_worker3event.dispose ();} Console.ReadLine (); } }}

It can be noted that task 1 is only blocking the Task2, but TASK3 is also affected by the timeout. The propagation of the time-out mechanism in the system will have a certain effect on the whole program.

Good aspect: Help all the modules of the system to understand that there are some anomalies in the system, to take action.
Bad aspect: some modules have no corresponding preparation for the timeout of other modules, which leads directly to a series of abnormal reactions, and the system crashes.

Synchronization across a process or AppDomain

If you need to implement a cross-process synchronization, you can use ManualResetEvent. There are certain differences between ManualResetEvent and ManualResetEventSlim, such as it has no isset attribute.

Method:

    • Reset: Set event to False (cancel setting/Cancel signal)
    • Set: Sets the event to true (set/signal), and if a task is waiting, it will get the signal and unblock it.
    • WaitOne: Blocks the current task or thread until another thread sends a signal.

The use of ManualResetEvent and ManualResetEventSlim is basically consistent.

The use of lightweight manual reset events for C # parallel programming

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.