Follow The Multithreaded Programming learning note--async and await (i)
Third, use the await operator for a continuous asynchronous task
This example learns how to read the actual flow of a program when there are multiple await method methods, and understand the asynchronous invocation of await.
1. The sample code is as follows.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; namespace threadasyncdemo{ class program { static void Main (string [] args) {
Console.WriteLine (String. Format ("-----use await operator----for continuous asynchronous Tasks");
Task T=Asyncwithtpl (); T.wait (); T=asyncwithawait (); T.wait (); Console.read (); } StaticTask Asyncwithtpl () {varContainertask =NewTask (() ={Task<string> Task1 = Getinfoasync ("TPL Task 1"); Task1. ContinueWith (Task={Console.WriteLine (Task1). Result); Task<string> Task2 = Getinfoasync ("TPL Task 2"); Task2. ContinueWith (Innertask=Console.WriteLine (innertask.result), taskcontinuationoptions.notonfaulted|taskcontinuationoptions.attachedtoparent); Task2. ContinueWith (Innertask=Console.WriteLine (innerTask.Exception.InnerException), taskcontinuationoptions.onlyonfaulted|taskcontinuationoptions.attachedtoparent); }, taskcontinuationoptions.notonfaulted|taskcontinuationoptions.attachedtoparent); Task1. ContinueWith (Task=Console.WriteLine (Task1. exception.innerexception), taskcontinuationoptions.onlyonfaulted|taskcontinuationoptions.attachedtoparent); } ); Containertask.start (); returnContainertask; } Async StaticTask asyncwithawait () {Try { stringresult =awaitGetinfoasync ("Async Task 1"); Console.WriteLine (result); Result=awaitGetinfoasync ("Async Task 2"); Console.WriteLine (result); } Catch(Exception ex) {Console.WriteLine (ex). Message); } } Async Statictask<string> Getinfoasync (stringname) {Console.WriteLine (string. Format ("Task {0} starts ... ", name)); awaitTask.delay (Timespan.fromseconds (2)); if(name=="TPL Task 2") Throw NewException (string. Format ("{0} throws exception information! ", name)); return string. Format ("Task {0} is running on thread id={1}. Whether this worker thread is a thread in the thread pool: {2}", Name,
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); } }}
2. Program run results, such as.
First, the program executes two asynchronous operations when it runs.
- Asyncwithawait method, which looks like the usual code, the only difference is that it uses two await declarations. The most important point is that the execution order of the code is still executed sequentially, and the code that invokes the asyncwithawait task will not start until the previous task is completed. When reading the code, the flow of the program is clear, you can see what is executed first, after what executes, but how does the program execute asynchronously? First, it is not always executed asynchronously, and we get the result of this task asynchronously only when we use await and a task is completed. Otherwise, when you see an await declaration in code, the behavior is that the code will return immediately when it executes to the await code line, and the rest of the code will run in a subsequent operation task. Therefore, waiting for the result of the operation does not block the execution of the program, which is an asynchronous call. When the code in the Asyncwithawait method executes, we can perform other tasks other than calling T.wait in the main method. However, the main thread must wait until all asynchronous operations are complete, or all background threads running asynchronous operations will stop running after the main thread finishes.
- The Asyncwithtpl method mimics the program flow of the asyncwithawait. We need a container task to handle all the interdependent tasks. It then starts the main task and adds a set of subsequent actions to it. When this task is completed, the result is printed. A task is then started, and after the task is completed, more subsequent operations are run in turn. To test the handling of the exception, an exception was deliberately thrown when the second task was run. and print out the exception information. This set of subsequent actions creates the same program flow as in the first method.
Ii. using the await operator for asynchronous tasks executed in parallel
This example learns how to use await to run asynchronous tasks in parallel, rather than using sequential execution in a general way.
1. The sample code is as follows.
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Threading;namespacethreadasyncdemo{classProgram {Static voidMain (string[] args) {Console.WriteLine (string. Format ("-----Use the await operator for asynchronous tasks that are executed in parallel----")); Task T=asyncprocess (); T.wait (); Console.read (); } Async StaticTask Asyncprocess () {Task<string> Task1 = Getinfoasync ("Task 1",3); Task<string> Task2 = Getinfoasync ("Task 2",5); string[] results =awaitTask.whenall (Task1, Task2); foreach(varIteminchresults) {Console.WriteLine (item); } } Async Statictask<string> Getinfoasync (stringNameintsecond) {Console.WriteLine (string. Format ("Task {0} starts ... ", name)); awaitTask.delay (Timespan.fromseconds (second)); //await Task.run (() = Thread.Sleep (Timespan.fromseconds (second)); return string. Format ("Task {0} is running on thread id={1}. Whether this worker thread is a thread in the thread pool: {2}", Name,
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); } }}
2. Program run results, such as.
Two asynchronous task Task1,task2 are defined in the asyncprocess method , running 3 seconds and 5 seconds, respectively. The results of two tasks are then obtained using Task.whenall assistance, and will not run until all the underlying tasks have been completed. Then we wait for the result of this combined task. After 5 seconds, we get all the results, stating that the tasks are running at the same time.
We look closely and find that the two tasks pretexting are executed by the same worker thread in the thread pool. How can this happen when we run the task in parallel? We comment out the await Task.delay line of code in the Getintroasync method and dismiss the comment for the await Task.run line of code, and then run the program again.
We will see that in this case, the two tasks will be executed by different worker threads. The difference is that Task.delay uses a timer behind the scenes, as follows: Gets the worker thread from the thread pool and waits for the Task.delay method to return the result. The Task.delay method then starts the timer and specifies a piece of code that is called after the timer time has elapsed to the number of seconds specified in the Task.delay method, and then immediately returns the worker thread to the thread pool. When the timer event runs, it also gets an available worker thread from the thread pool (possibly the same worker thread that was running last), and runs the code specified by the timer.
When you use the Task.run method, you get a worker thread from the thread pool and block it for a few seconds, and then get the second worker thread and block it. In this case, we consume two worker threads, but nothing happens. Such as. The difference between the two is that two of the tasks are running on different threads.
Multithreaded Programming learning Notes--async and await (ii)