Async traps in C #

Source: Internet
Author: User

This article introduces the common asynchronous traps in asynchronous programming:

1. Async does not run asynchronously

Let's take a look at the code below and guess how he printed out the following three strings:

/*Gotcha #1: Async does not run asynchronously*/Static voidMain (string[] args) {Console.WriteLine ("begin"+"""+ DateTime.Now.ToString () +"""); varChild =gotcha1.workthenwait (); Console.WriteLine ("started"+"""+ DateTime.Now.ToString () +"""); Child.    Wait (); Console.WriteLine ("completed"+"""+ DateTime.Now.ToString () +"""); Console.readkey ();} Public Static AsyncTask workthenwait () {Thread.Sleep ( the); Console.WriteLine (" Work"+"""+ DateTime.Now.ToString () +"""); awaitTask.delay (10000);}

Look at this code, and if you suspect that he will print "Begin", "started", "work", "completed" in order, then you are wrong. This code will output "Begin", "work", "Started", "completed".

As you can see, this code would have guessed that because the Workthenwait () method contains a heavy time-consuming task (here, Thread.Sleep (5000)), it is intended to allow him to execute the method asynchronously, but It can be seen that the await keyword was used after the heavy time-consuming task of the segment, so behind the child. The wait () method only waits for the execution of Task.delay (10000).

The results of the implementation are as follows:

2. Ignore results

Let's take a look at the code below, guess how he did it, and whether it would wait:

/*Gotcha #2: Ignoring results*/Static voidMain (string[] args)    {Gotcha2.handler (); Console.readkey ();} Public Static AsyncTask Handler () {Console.WriteLine ("before"); Task.delay ( the); Console.WriteLine (" After");}

Looking at this code, do you expect it to print "before", wait 5 seconds, and then print "after"? Of course, it's wrong again. He will immediately print two strings, directly without any waiting. The problem is that although Task.delay returns the task return value, we forget to use the await keyword to wait until he finishes.

The results of the implementation are as follows:

3. Async void method

Let's take a look at the code below to determine if the exception message will be printed successfully:

/*Gotcha #3: Async void Methods*/Static voidMain (string[] args)    {Gotcha3.callthrowexceptionasync (); Console.readkey ();}Private Static Async voidThrowexceptionasync () {Throw NewInvalidOperationException ();} Public Static voidCallthrowexceptionasync () {Try{throwexceptionasync (); }    Catch(Exception) {Console.WriteLine ("Failed"); }}

Do you think this piece of code will print "Failed"? Of course, this exception is not captured because the Throwexceptionasync method starts executing and returns immediately (this exception occurs inside the background thread). The problem is that for example, async void Foo () {...}, this method, the C # compiler generates a method that returns void and then creates a task in the background and executes it. This means you don't know when the job actually happened.

4. Async void lambda function

If you are passing an asynchronous lambda function as a delegate to a method. In this case, the C # compiler infers the type of the method from the delegate type. If you use the action delegate, the compiler generates an async void function (this background startup thread works and returns void). If you use func<task> delegate, the compiler generates a function that returns a Task.

Let's take a look at the code below to see if the code is executed after 5 seconds (waiting for all of the task to complete sleeping), or is it done immediately?

/*Gotcha #4: Async void lambda functions*/Static voidMain (string[] args)    {gotcha4.test (); Console.WriteLine ("OK");} Public  Static voidTest () {Parallel.For (0,Ten,Asynci = {        awaitTask.delay ( the); });}

Of course, looking directly at for cannot tell if he is waiting, we use the gadget to look at the following code source:

 Public void TestMethod () {    parallel.for (0)async i = {        await Task.delay (();    });}
//Asyncgotchaslib.class1 Public voidTestMethod () {intArg_23_0 =0; intArg_23_1 =Ten; Action<int>Arg_23_2; if((arg_23_2 = class1.<>c.<>9__0_0) = =NULL) {Arg_23_2= (Class1.<>c.<>9__0_0 =Newaction<int> (class1.<>c.<>9.<testmethod>b__0_0)); } parallel.for (Arg_23_0, Arg_23_1, arg_23_2);}

As you can see for, the lambda function is finally compiled for action Delegate, so this code does not wait 5 seconds, it will execute immediately, and its wait will be executed in the background thread.

5. Nesting Tasks

Look at the following code, the question is, the following two print directly will not wait for 5 seconds:

/*Gotcha #5: Nesting of tasks*/Static voidMain (string[] args)    {gotcha5.test (); Console.readkey ();} Public Async Static voidTest () {Console.WriteLine ("before"); awaitTask.Factory.StartNew (Async() = {awaitTask.delay ( the); Console.WriteLine ("background thread waits 5 seconds after");    }); Console.WriteLine (" After");}

Again, quite unexpectedly, there is no waiting between two prints ("before", "after"). Why? The Stratnew method takes a delegate and returns a Task<t>, where T is the type that delegate returned. In this method, the delegate returns a Task, so we get a result of task<task>. Using the await keyword waits only for the completion of the external task (which immediately returns an internal task), which means that the internal task is ignored and the internal task executes in the background thread.

Async traps in C #

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.