[Asynchronous programming you must know] C #5.0 new features -- Async and Await make asynchronous programming easier

Source: Internet
Author: User
Tags apm call back

 

In the previous C # Basic Knowledge series, I only introduced the main features from C #1.0 to C #4.0. the launch of NET 4.5 has added new features for C #-The async and await keywords in C #5.0. These two keywords simplify asynchronous programming and simplify the process, or because the compiler has done more work for us, let's take a look at the complex work behind the compiler.

Everyone is certainly familiar with the synchronized code, because most of the code we usually write is synchronized, but the synchronization code has a very serious problem, for example, when we send a request to a Web server, if the request code is synchronous, our application will be in the waiting state until a response message is retrieved, however, in this waiting status, the user cannot operate any UI interface and there is no message. If we try to operate the interface, at this point, we will see the "application as a response" Information (beside the application window). I believe that when you usually use desktop software or access the web, you must have encountered such a similar situation. For this, you will surely feel very uncomfortable. This is because the implementation of the code is synchronized. Therefore, before a response message is received, the interface becomes stuck, therefore, this is unacceptable for users, because if I want to download a large file from the server, we cannot even close the form. To illustrate the problems with the synchronization code (causing the interface to start), we will use a program to help you better understand the problem:

          btnClick_Click(.btnClick.Enabled =  length =.btnClick.Enabled = .richTextBox1.Text += String.Format(=  =             HttpWebRequest webRequest = WebRequest.Create()  (webRequest !=                  (WebResponse response = (Stream responseStream ==

After running the program, when we click the "Click me" button in the form, we cannot perform any operations on the form, including moving the form or closing the form, before getting the server response, the specific running result is as follows:

The above section shows the actual problems caused by the synchronization method. To solve similar problems ,. NET Framework has long provided support for asynchronous programming. the asynchronous programming model (APM) proposed in NET 1.0 solves the above problem. The specific code is as follows (the annotation part obtains the above object for GUI thread synchronization, then synchronously call the post method of the synchronization context object and hand over the method to be called to the GUI thread for processing, because the control was originally created by the GUI thread, then it executes the access control operation on its own, so there is no cross-thread problem. The program uses the callRichTextBoxControlInvokeThe method for asynchronous callback to access the control is actually the same as the comments.RichTextBoxControlInvokeMethod to obtain the thread information for creating the RichTextBox Control (that is, the synchronization context of the previous method), and then let the Invoke callback method run on this thread ):

  btnClick_Click(= = = caller.BeginInvoke(GetResult,                                   ( i = ; i < ; i++          =             resultvalue =          ShowState(==         

The running result is:

The above section demonstrates how to use the traditional asynchronous programming model (APM) to solve the problems of Synchronous Code. NET 2.0 ,. NET 4.0 and. in NET 4.5, Microsoft has released new methods to solve the problem of Synchronous Code. They are event-based Asynchronous modes, respectively, supports asynchronous programming based on the asynchronous mode of tasks and the async and await keywords. I have introduced the first two asynchronous programming modes in my previous articles. You can refer to the relevant articles for details, this section describes how to implement asynchronous programming using the async and await keywords in C #5.0. The following code demonstrates how to use async and await keywords to implement asynchronous programming. You can also refer to the previous blog to compare and understand that async and await are easier to use asynchronous programming.

     btnClick_Click( length = .richTextBox1.Text += String.Format(=          Task<>=             HttpWebRequest webRequest = WebRequest.Create()  (webRequest !=                  (WebResponse response =  (Stream responseStream == .richTextBox1.Text += 

The running result is as follows:

We will compare the above Code that uses the async and await keywords to implement asynchronous programming and the synchronization code in the second part.Are there any asynchronous implementations and Synchronous Code implementations using the async and await keywords?Asynchronous methods run on GUI threads, so you do not need to consider cross-thread access as in APM (because when the ininvoke method is delegated for callback, the callback method is executed on the thread pool thread)

For the code of the button click event, the code generated by the compiler is as follows, exactly like the code in our source code:

  btnClick_Click(<btnClick_Click><>4__this = ==<>t__builder =<>1__state = -<>t__builder.Start<<btnClick_Click>d__0>(

Seeing the above Code, as a programmer, I want to say-how can you use the compiler like this? How can I tamper with my code at will? Does this not infringe my copyright? At least let me know if you want to change it. If my source code shows that its implementation in the compiler is the same as above, I believe that my source code will say-do I have the most vicious face in the world? Well, in order to make everyone better understand what is done behind the compiler, we will follow the above Code to find out, I also want to show you how to find the ing between the compiler code and the source code. My analysis ideas are as follows:

1. Ask a question-where is the source code of my click event?

From the compiler code, we can see that the first seven sentences of code all assign values to a class. The most effective thing is the call of the Start method. Here are a few more questions-with these two questions, we can click <btnClick_Click> d _ 0 (the reflection tool allows us to directly click to view) to see what type it is.

<BtnClick_Click> <> Form1 <> AsyncVoidMethodBuilder <> TaskAwaiter <> <length> <> CS $ <> t _ doFinallyBodies = (. <>-// The implementation principle behind the async and await keywords is task-based asynchronous programming mode (TAP)
CS $ =. <> (CS $
. <> 1 _ state =. <> u __$ awaiter2 = CS $
. <> T _ builder. awaitUnsafeOnCompleted <TaskAwaiter <>, Form1. <btnClick_Click> d _ 0> (CS $, <> t _ doFinallyBodies = // when the task is completed, the following code is not executed, the Code CS $ = in Label_007A will be executed directly. <>. <> u __$ awaiter2 = TaskAwaiter <>. <> 1 _ state =-// the following code is executed on the GUI thread.CS $ = TaskAwaiter <> CS $ = CS $. <length> 52.161 = CS $ this. <> 4 _ this. otherWork (); this. <> 4 _ this. richTextBox1.Text = this. <> 4 _ this. richTextBox1.Text + string. format ("\ n reply Byte Length: {0 }. \ r \ n ", this. <length> 52.161); this. <> 4 _ this. txbMainThreadID. text =Thread. CurrentThread. ManagedThreadId. ToString ();} (Exception <>. <> 1 _ state = -. <> t _ builder. setException (<>. <> 1 _ state = -. <>. <>

If you have read my iterator topic, I believe you can think that this struct is an implementation of an iterator. The main method is the MoveNext method. The comments from the above Code should help us solve the first problem mentioned in step 1, that is, the type of <btnClick_Click> d _ 0. Next we will analyze the second problem, from the code of the <btnClick_Click> d _ 0 struct, we can find that the type of <> t _ builder is AsyncVoidMethodBuilder, next let's take a look at its explanation of the Start Method -- run the generator of the correlated state machine, that is, call this method to Start running the state machine, running a state machine refers to executing the MoveNext method (the MoveNext method contains all the code in our source code, so that the Click method generated by the compiler is associated with our source code ). From the above Code comment, we can find that when MoveNext is called, it will return to the GUI thread immediately, and there are also such questions-when the MoveNext method was called at the beginning, the task has not been completed yet, but the code in our source code must be output and wait until the task is completed (because the task is completed before it can be transferred to the Code in Label_007A ), in this case, we should call back the MoveNext method to check whether the task is completed. (for example, in the iterator, we need to use the foreach statement to always call the MoveNext method ), however, we have not found any code for callback in the code? For this question, the callback MoveNext method certainly exists, but for the first time, the friends who read the Code have not found similar statements, I mentioned a problem in the code comment above-what is the purpose of this code? Let's take a look at the analysis below. In fact, the following code is used to call back the MoveNext method, AsyncVoidMethodBuilder. the AwaitUnsafeOnCompleted <TAwaiter, TStateMachine> method is to schedule the state machine to execute the MoveNext method, which solves the MoveNext callback question.

I believe you can find the corresponding relationship between the source code and the compiler code from the above explanation, but after analyzing the above, I have another question: when the task is completed, how does one exit the MoveNext method? You cannot keep the callback. As shown in the preceding Code, after the task is executed, the value of <> 1 _ state is set to 0, when the MoveNext method is called back next time, the method will exit directly. However, before the task is completed, the <> 1 _ state is set to 0, however, the Code after the Switch part sets <> 1 _ state to-1, which ensures that the MoveNext method can be repeatedly called back before the task is completed, after the task is completed, the Code <> 1 _ state is not executed, but is transferred to Label_007A.

After the above analysis, I believe you can also develop a set of asynchronous analysis methods.AccessWebAsync() The analysis logic is the same as that of btnClick_Click.

After the analysis, I will share several questions about async and await.

Question 1: is a method written with the async keyword indicating that this method is an Asynchronous Method without blocking the thread?

Question 2: will the "async" keyword cause the call method to run in the thread pool thread?

.

For more frequently asked questions about async and await keywords, refer to -- Async/Await FAQ and Chinese Translation -- FAQs about async and await

The content of this topic is introduced here, and I will also synchronize the content of this topic to the index of the previous C # Basic Knowledge series, in this way, my C # feature series will be complete, and this topic is also the last topic of asynchronous programming. In the subsequent topics, we will implement a multi-task and multi-thread download tool similar to thunder, this topic may use the content of parallel programming, so I will share with you the content of parallel programming.

 

For those who are just using await, they often ask "help me to see how the deadlock has occurred. What should I do ?", For such a problem, we should understand that --The Asynchronous Method identified by async runs on the GUI thread (for this, you must understand that the reason is also described in the Analysis Section in my article, people who read this article should be familiar with it), so they don't need to consider cross-thread access as in APM..

 

Download all source code for this topic: ASyncAndAwaitTestProject.zip

 

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.