C # Parallel Tasks multiple optimization scheme sharing (asynchronous delegation)

Source: Internet
Author: User

Encountered a multi-threaded task optimization problem, now solved, share the following.

Suppose there are four tasks:

Task 1: Login Verification (CheckUser)

Task 2: Obtain data from the Web service after validation succeeds (Getdatafromweb)

Task 3: Obtain data from the database after successful validation (GETDATFROMDB)

Task 4: Execute a method with 2, 3 data (startprocess)

A rather stupid method (the first method I remember as Method 1) is to open a thread directly and perform four tasks sequentially in sequence:


New Thread (delegate
{
CheckUser ();
Getdatfromdb ();//Get data from a database
Getdatafromweb ();//web Service Get Data
StartProcess ();//Execution 4
}). Start ();

But careful analysis of the requirements we will find that task 2 and task 3 do not have a distinction, in fact, there is no correlation between the two, but the implementation of Task 4 requires that tasks 2 and 3 have been completed as a condition, so we can open two more threads to perform task 2 and task 3, when both are completed, perform task 4.

Here, two global variables are used to represent the state of Task 2 and Task 3. Perform tasks 2, 3, 4, respectively, with three threads, where task 4 has been looping through the status of global variables to ensure that the execution is performed after 2 and 3 are complete.

This is recorded as Method 2:


private static volatile bool _m2;//the flag bit of Task 2
private static volatile bool _m3;//the flag bit of task 3
private static void Main (string[] args)
{
New Thread (delegate
{
CheckUser ();
New Thread (delegate
{
Getdatfromdb ();//Get data from a database
_m2 = true;//Flag position is true
}). Start ();
New Thread (delegate
{
Getdatafromweb ();//web Service Get Data
_M3 = true;//Flag position is true
}). Start ();
New Thread (delegate
{
while (!) ( _M3 && _m2)//Determine if Tasks 2 and 3 have been executed
{
Thread.Sleep (100);
}
StartProcess ();//Perform Task 4
_M2 = true;
}). Start ();
}). Start ();
}

The above code has basically been able to achieve the desired goal, but because of the use of two global variables, although there is no problem of synchronization conflicts, but always feel very uncomfortable, and when we need to do the expansion, for example, before the implementation of Task 4, we also need to load the data in the file ( Getdatafromfile), then we have to add another global flag bit, which is a bit of a hassle.

In fact, the thread class itself already has the perfect solution for this situation,--join.

Thread.Join method
During the continuation of standard COM and SendMessage message pump processing, the calling thread is blocked until a thread terminates.

To put it simply, join is a blocking method, thread 2 is created in threads 1, and Thread 2 's join method is called, then thread 1 will be blocked until thread 2 is executed. The above example is to create a thread of Task 2 and Task 3 within Task 4, the Join method that invokes the thread of Task 2 and task 3 to block Task 4 until Task 2 and task 3 are completed before proceeding to Task 4. This is written as Method 3 and the code is as follows


private static void Main (string[] args)
{
New Thread (delegate
{
CheckUser ();
New Thread (delegate
{
Thread task2 = new Thread (delegate
{
Getdatfromdb (); Getting data from a database
});
Thread task3 = new Thread (delegate
{
Getdatafromweb (); Web Services Get Data
});
Task2. Start ();
Task3. Start ();
Task2. Join ();//Task 2 blocking
Task3. Join ();//Task 3 blocking
StartProcess (); Perform Task 4
}). Start ();
}). Start ();
}

This will not require any sign-up. This is the ideal solution.

There is also a solution that uses the EventWaitHandle

The EventWaitHandle class allows threads to communicate with each other by signaling and waiting for signals. An event wait handle (referred to as an event) is a wait handle that can release one or more waiting threads by emitting a corresponding signal. After the signal is issued, the event wait handle can be reset manually or automatically

In short, it is the advanced version of Method 2, which uses EventWaitHandle to control the state without using the while loop to listen, but still requires two global eventwaithandle objects. This method is recorded as Method 4, the code is as follows

private static EventWaitHandle eventWait1 = new EventWaitHandle (false, Eventresetmode.autoreset);//initialization state false;
private static EventWaitHandle eventWait2 = new EventWaitHandle (false, Eventresetmode.autoreset);//initialization state false;
private static void Main (string[] args)
{
New Thread (delegate
{
CheckUser ();
New Thread (delegate
{
Getdatfromdb (); Getting data from a database
Eventwait1.set (); Flag position is True
}). Start ();
New Thread (delegate
{
Getdatafromweb (); Web Services Get Data
Eventwait2.set (); Flag position is True
}). Start ();
New Thread (delegate
{
Eventwait1.waitone ();//Task 2 blocking, waiting
Eventwait2.waitone ();//Task 3 blocking, waiting
StartProcess (); Perform Task 4
}). Start ();
}). Start ();
}

The above three optimization schemes, in fact, the core idea is the same, all by opening 3 threads to perform 2, 3, 4 tasks, where task 4 is blocked (while loop, Eventwait.waitone,thread.join), when the blocking is lifted, continue to perform task 4. In other words, Task 4 is actually waiting for Task 2 and Task 3 to complete. So, is there a way for Task 2 and task 3 to proactively notify task 4? That is, when Task 2 and task 3 are complete, you are actively performing task 4.

Method of course there are: asynchronous Delegate + callback function

private static Object obj = new Object ();
private static volatile bool _m2;//the flag bit of Task 2
private static volatile bool _m3;//the flag bit of task 3

private static void Main (string[] args)
{
CheckUser (); The first step verifies the user
Action Step2 = Delegate
{
Getdatfromdb (); Getting data from a database
_M2 = true; Flag position is True
};
Action Step3 = Delegate
{
Getdatafromweb (); Web Services Get Data
_M3 = true; Flag position is True
};

Step2. BeginInvoke (delegate
{
if (_m2 && _m3)//through the flag bit to determine whether 2 3 has been completed
{
Lock (obj)//Locking
{
_m2 = false;
if (_M3)//double verification to prevent both simultaneous entry
StartProcess (); Perform 4
}
}
}, NULL);
Step3. BeginInvoke (delegate
{
if (_m2 && _m3)//through the flag bit to determine whether 2 3 has been completed
{
Lock (obj)
{
_M3 = false;
if (_m2)
StartProcess (); Perform 4
}
}
}, NULL);
}

Explain the code. The delegate objects Step2 and step3 for Task 2 and task 3 were created in the first way. Executes the asynchronous invocation method Beginvoke for both delegates. Executing Beginvoke, a new thread is created to execute the Step2 and Step3 methods, and a callback function is specified when the BeginInvoke is executed

Delegate
{
if (_m2 && _m3)//through the flag bit to determine whether 2 3 has been completed
{
Lock (obj)
{
_M3 = false;
if (_m2)
StartProcess (); Perform 4
}
}
}

This function is called after the Step2 and Step3 threads have finished executing. Here, again, I used the flag to determine if Step2 and step3 have been completed, and to prevent a special situation: "The time that Step2 and step3 execute are almost equal, they will be judged by if (_M2&&_M3) at the same time, And then execute two times startprocess "lock lock is added here, and the flag bit is reset + double judgment in lock lock (here you can refer to the dual locking principle of the singleton mode) to ensure that the starprocess is executed only once.

This way, the parallel task of an active notification pattern is implemented, but this implementation is much more cumbersome than Method 2, especially in the case of concurrency, where the individual feels less practical.

In addition, you can use the observer pattern to implement the effect of the asynchronous Delegate + callback function.

C # Parallel Tasks multiple optimization scheme sharing (asynchronous delegation)

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.