We often encounter the need to use parallel processing to maximize the potential of multiple cores or CPUs to improveProgramThe scenario of operational efficiency. In the. NET environment, a common practice is to use thread and multithreading for parallel processing. However, in. net4.0, Microsoft provided a new concept-task. In other words, parallel processing evolved from multi-thread to multi-task.
I. Multi-task processing using tasks
Test 1:
The following is the test process. It simulates multiple calls of a time-consuming method and uses the serial, multi-thread, and multi-task methods:
1. Create a virtual time-consuming Method
/// <Summary>
/// Method for simulating execution time consumption
/// </Summary>
Public Static Void Testlongtimemethod ()
{
Console. writeline ( " Method start: " + System. datetime. Now. tostring ());
System. Threading. thread. Sleep ( 5000 );
Console. writeline ( " Method end: " + System. datetime. Now. tostring ());
}
2. Traditional serial call methods, multi-thread calls, and multi-task calls
# RegionTraditional serial mode
/// <Summary>
///Traditional serial mode
/// </Summary>
Public Static VoidLinemethod ()
{
Testlongtimemethod ();
Testlongtimemethod ();
Testlongtimemethod ();
}
# Endregion
# Region Multithreading
/// <Summary>
/// Multithreading
/// </Summary>
Public Static Void Threadmethod ()
{
VaR Thread1 = New Thread () => testlongtimemethod ());
VaR Thread2 = New Thread () => testlongtimemethod ());
Thread1.start ();
Thread2.start ();
Testlongtimemethod ();
Thread1.join ();
Thread2.join ();
}
# Endregion
# Region Multitasking
/// <Summary>
/// Multi-task mode-the thread pool, which is delegated to the CPU. After all tasks are executed, the thread pool jumps out.
/// </Summary>
Public Static Void Taskmethod ()
{
// Method 1: with parallel. invoke, you can run multiple tasks in parallel at the same time. The method called by the task can be different.
// Parallel. Invoke (
// () => Testlongtimemethod (),
// () => Testlongtimemethod (),
// () => Testlongtimemethod ()
// );
// Method 2: With parallel. For, you can set multiple tasks in parallel, and the method called by the task is the same.
Int Times = 3 ;
Parallel. (
0 ,
Times,
I => testlongtimemethod ()
);
}
# Endregion
3. Simulate the execution process.
Static Void Main ( String [] ARGs)
{
Int Maxtimes = 1 ;
Datetime DS = New Datetime ();
Datetime de = New Datetime ();
Datetime ds1 = New Datetime ();
Datetime de1 = New Datetime ();
Datetime ds2 = New Datetime ();
Datetime de2 = New Datetime ();
# Region Linemethod serial
Console. writeline ( " * ************ [String line ]************** " );
DS = datetime. now;
Console. writeline ( " * ************* [Starttime: " + Ds. tostring () + " ] *************** " );
For ( Int Intloop = 0 ; Intloop <maxtimes; intloop ++)
{
Console. writeline ( " **************[ " + (Intloop + 1 ). Tostring () + " ] *************** " );
Linemethod ();
}
De = datetime. now;
Console. writeline ( " * ************* [Endtime: " + De. tostring () + " ] *************** " );
System. Threading. thread. Sleep ( 500 );
# Endregion
# Region Threadmethod Multithreading
Console. writeline ( " ]************** " );
Ds1 = datetime. now;
Console. writeline ( " * ************* [Starttime: " + Ds1.tostring () + " ] *************** " );
For ( Int Intloop = 0 ; Intloop <maxtimes; intloop ++)
{
Console. writeline ( " **************[ " + (Intloop + 1 ). Tostring () + " ] *************** " );
Threadmethod ();
}
De1 = datetime. now;
Console. writeline ( " * ************* [Endtime: " + De1.tostring () + " ] *************** " );
System. Threading. thread. Sleep ( 500 );
# Endregion
# Region Taskmethod multi-task
Console. writeline (" ]************** " );
Ds2 = datetime. now;
Console. writeline ( " * ************* [Starttime: " + Ds2.tostring () + " ] *************** " );
For ( Int Intloop = 0 ; Intloop <maxtimes; intloop ++)
{
Console. writeline ( " **************[ " + (Intloop + 1 ). Tostring () + " ] *************** " );
Taskmethod ();
}
De2 = datetime. now;
Console. writeline ( " * ************* [Endtime: " + De2.tostring () + " ] *************** " );
System. Threading. thread. Sleep ( 500 );
# Endregion
Console. writeline ( " Linemethod [String line ]: " + (De-Ds). totalmilliseconds. tostring ());
Console. writeline ( " Threadmethod [multithreading ]: " + (De1-ds1). totalmilliseconds. tostring ());
Console. writeline ( " Taskmethod [multi-task ]: " + (De2-DS2). totalmilliseconds. tostring ());
Console. Readline ();
}
4. Execution result
Conclusion: The results show that the performance of multi-thread or multi-task is significantly higher than that of serial mode. Multi-threaded or multi-task execution efficiency is not much different, and the underlying implementation of the. NET Framework may be roughly the same. But multitaskingCodeThe statement is more concise and flexible.
Ii. Use tasks to implement parallel and serial execution sequence Definitions
Test 2 ::
1. Assume that the execution sequence of multi-task A, B, C, D, and E is: After A and B are executed, C and A are executed. After D and B are executed, e is executed.
The test method is as follows (that is, the execution name is displayed during execution, and the process sleep time is determined based on the input time parameter ):
Public Class Testaction
{
Private Int _ P;
Private String _ Actionname;
Public Testaction ( String Actionname, Int P)
{
_ Actionname = actionname;
_ P = P;
}
Public Void Do ()
{
Console. writeline (system. datetime. Now. tostring () + " | Start execution " + _ Actionname );
Thread. Sleep ( New Timespan ( 0 , 0 , _ P ));
Console. writeline (system. datetime. Now. tostring () + " | Execution completed " + _ Actionname );
}
}
2. test method (combining traditional serial and serial parallel)
Assume that each task takes a (5 seconds), B (5 seconds), C (2 seconds), D (1 second), and E (2 seconds ). It takes 5 + 5 + 2 + 1 + 2 = 15 seconds for serial communication, and concatenates (a, B-> C, A-> D, B-> E) it takes 5 + 2 = 7 seconds.
The test procedure is as follows:
/// <Summary>
/// Test in the designed sequence (both serial and parallel): A, B-> C, A-> D, B-> E
/// </Summary>
Public Static Void Sorttaskmethod ()
{
Console. writeline ( " -------------- [Serial] -------------- " );
( New Testaction ( " A " , 5 ). Do ();
( New Testaction ( " B " , 5 ). Do ();
( New Testaction ( " C " , 2 ). Do ();
( New Testaction ( " D " , 1 ). Do ();
( New Testaction ( " E " , 2 ). Do ();
Console. writeline ( " -------------- [Multi-task] -------------- " );
Taskfactory factory = New Taskfactory ();
Task A = factory. startnew (( New Testaction ( " A " , 5 ). Do );
Task B = factory. startnew (( New Testaction ( " B " , 5 ). Do );
Task c = factory. continuewhenall ( New Task [] {a, B}, (pretasks) => ( New Testaction ( " C " , 2 ). Do ()));
Task d = factory. continuewhenall ( New Task [] {A}, (pretasks) => ( New Testaction ( " D " , 1 ). Do ()));
Task E = factory. continuewhenall (New Task [] {B}, (pretasks) => ( New Testaction ( " E " , 2 ). Do ()));
}
3. Execution result
Conclusion: The results are consistent with the expected test results.
Key code for implementation:
// Declare and obtain a task factory instance
Taskfactory factory = New Taskfactory ();
// Create a task using the factory and execute the specified Method
Task A = factory. startnew (( New Testaction ( " A " , 5 ). Do );
// Use the factory to create subsequent tasks (based on the pre-tasks) and execute the specified Method
Task c = factory. continuewhenall ( New Task [] {a, B}, (pretasks) => (New Testaction ( " C " , 2 ). Do ()));
Note that the preceding task instances obtained using the factory method have important differences with the parallel. Invoke method described earlier:After obtaining the task instance in the factory mode, it is assigned to the system delegate, which is not subject to the method constraints currently called. However, in the invoke mode, all the tasks declared in parentheses must be completed, will jump out of the invoke and return to the method currently called.