Explore the Async and Await analysis of c #

Source: Internet
Author: User
Tags apm

Explore the Async and Await analysis of c #
Async and Await are newly added asynchronous programming methods in net4.x. The objective of Async and Await is to simplify asynchronous programming. The following is a simple comparison with the previous APM method. In APM mode, BeginGetRequestStream needs to pass in the callback function. When the thread encounters BeginXXX, it will continue to execute the following logic in non-blocking form. After the execution, it calls back the previously passed-in function. HttpWebRequest myReq = (HttpWebRequest) WebRequest. create ("http://cnblogs.com/"); myReq. beginGetRequestStream (); // to doAsync. Use Async to mark Async1 as an Asynchronous Method, and use Await to mark GetRequestStreamAsync to indicate time-consuming operations in the method. When the main thread encounters await, it will return immediately and continue to execute the logic below the main thread in non-blocking form. When await completes the time-consuming operation, continue to execute the logic below Async1

static async void Async1()    {        HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("http://cnblogs.com/");        await myReq.GetRequestStreamAsync();        //to do    }     

 

The above is the asynchronous Implementation of the net class library, if you want to implement your own method asynchronous. APM mode:
    public delegate int MyDelegate(int x);           MyDelegate mathDel = new MyDelegate((a) => { return 1; });         mathDel.BeginInvoke(1, (a) => { },null);

 

Async mode:
static async void Async2()    {        await Task.Run(() => { Thread.Sleep(500); Console.WriteLine("bbb"); });        Console.WriteLine("ccc");    }  Async2();  Console.WriteLine("aaa");

 

The comparison shows that async/await is very concise and elegant, and requires less code, which is more in line with people's writing habits. Because human thinking is better at understanding linear steps. The execution steps of APM asynchronous callback are: A logic-> false C callback logic-> B logic-> true C callback logic, which can cause confusion to some extent, when a project has a large number of asynchronous callbacks, it becomes difficult to maintain them. The addition of Async and Await makes the original chaotic steps Correct again, and the execution steps are: A logic-> B logic-> C logic. As a programmer's self-cultivation, the basic principle analysis is very important to be curious. When Async came out, it would make people feel confused. How can await be returned directly? How can Microsoft develop a new asynchronous model. This is because we are used to the non-linear method of APM, but it is hard to understand it now. When learning Async, you can use the existing APM method to understand it. The following code is purely fictitious. For example, imagine the Async3 method of the APM method using the Async2 method:
Static async void Async3 () {var task = await Task. run () => {Thread. sleep (1, 500); Console. writeLine ("bbb") ;}); // call back the task after the task is registered. registerCompletedCallBack () => {Console. writeLine ("ccc ");});}

 

I can see it above for better understanding, and then imagine the Async3 method Async4 method:
Static void Async4 () {var thread = new Thread () => {Thread. sleep (1, 500); Console. writeLine ("bbb") ;}); // callback after the thread is registered. registerCompletedCallBack () => {Console. writeLine ("ccc") ;}); thread. start ();}

 

This looks very simple and clear, and even async is removed, becoming familiar with programming habits. Although the Code is purely fictitious, the basic idea is the same, and the difference lies in the implementation details. Internal implementation analysis, as a programmer's self-cultivation, is more rigorous. Although the above basic ideas are well understood, the specific details are that programming is not a bit of a false job, and the virtual code can't help but look at the officials. Continue to look at the Async2 method. The complete Code after decompiling is as follows: View Code finds that async and await are gone, and it turns out to be the syntactic sugar optimization provided by the compiler level, so async is not a completely new asynchronous model. It can be understood that async is more of a regression of linear execution steps, specifically designed to simplify asynchronous code writing. The decompiled Code shows that the compiler generates a new state machine structure asyncd that inherits IAsyncStateMachine (<Async2> d _ 2 in the code, which is abbreviated as AsyncD ), the following is an analysis based on the decompiled code. The most basic State Machine Interface Definition of IAsyncStateMachine:
public interface IAsyncStateMachine{    void MoveNext();    void SetStateMachine(IAsyncStateMachine stateMachine);}

 

Since there is no obstacle to async and await syntax sugar, you can understand the Code Execution Process in a linear order. The entire execution steps are as follows: 1. the main thread calls Async2 () method 2. in Async2 () method, the initialization state machine state is-1. When AsyncD3. MoveNext is started, the task is executed. the run function throws a task into the thread pool and returns a waiting task handle. MoveNext source code analysis: // delegate Program to execute the task. CS $ <> 9 _ CachedAnonymousMethodDelegate1 = new Action (Program. <Async2> B _ 0); // start to use tasks for Asynchronization. net4.0 is a task-based programming method. Awaiter = Task. run (Program. CS $ <> 9 _ CachedAnonymousMethodDelegate1 ). getAwaiter (); // set the status to 0, so that MoveNext can directly break and execute the logic behind the switch, a typical state machine mode. This. <> 1 _ state = 0; // return the thread that calls the async2 method, so that it can continue to execute the logic behind the main thread this. <> t _ builder. awaitUnsafeOnCompleted <TaskAwaiter, Program. <Async2> d _ 2> (ref awaiter, ref this); return; 4. now two threads are running, the main thread and Task. the running task thread. 5. Output aaa logic after the execution of the main thread, bbb output after the task thread is completed, and ccc output after the execution of the business logic after the task thread is continued.
Label_0090: awaiter.GetResult(); awaiter = new TaskAwaiter();Console.WriteLine("ccc");

 

It can be understood that async splits the entire main thread synchronization logic into two parts. The first part is directly executed in the main thread, the second is executed after the task thread is completed, and the second is running in the middle of the task thread. The source code is awaiter. getResult () is to execute the second block after the task thread is completed. From the user's perspective, the execution steps are: main thread A logic-> asynchronous task thread B logic-> main thread C logic.
Test (); Console. writeLine ("A logic"); static async void Test () {await Task. run () => {Thread. sleep (1, 1000); Console. writeLine ("B logic") ;}); Console. writeLine ("C logic ");}

 

Looking back and comparing the fictitious method Async4 () in the Basic Principle Analysis Section, we find that the difference is that one is callback after completion, and the other is execution after completion, this is also the most basic Asynchronous Method. Note: main thread A logic> asynchronous task thread B logic> main thread C logic. Note: The three steps may use the same thread, or two or even three threads. You can use Thread. CurrentThread. ManagedThreadId to test it.
     Async7();     Console.WriteLine(Thread.CurrentThread.ManagedThreadId);     static async void Async7()    {        await Task.Run(() =>        {            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);         });        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);     }

 

It is because of this that some comments say that Async does not need to open a thread, or that it needs to open a thread. In a single aspect, it is both right and wrong. The above source code is analyzed in a concise manner. The specific async involves thread context switching, thread reuse, scheduling, and so on. For more information, see ExecutionContextSwitcher, SecurityContext. RestoreCurrentWI, and ExecutionContext. In fact, you don't need to worry too much about the details of the physical thread. You just need to know the basic principle of [main thread A logic-> asynchronous task thread B logic-> main thread C logic. In addition, Async also has thread overhead, so it should be reasonably used in different business scenarios. Summary from the gradual Analysis of Async, it is found that the asynchronous method provided by Net is basically the same in the same line, for example: 1. Async of net4.5, throwing away the syntax sugar is the Task + state machine of Net4.0. 2. For net4.0 tasks, degradation to 3.5 is (Thread, ThreadPool) + Implementation of wait, cancel, and other API operations. Starting from async, This article briefly analyzes its internal principles and implementation, hoping to help you.

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.