. NET (C #): Await an Async method that returns a task

Source: Internet
Author: User

As we all know, the Async method can only return Void,task and task<t>.

For an async method that returns void, it is not awaitable, so the other method cannot invoke it with the await method, and the Async method that returns a task can.

So when the Async method returns a task, then await, what is the concept of the await task? Is the first await task in the Async method? No, it represents the full execution of the target async method, including the join task being split by await, but does not include multithreaded execution caused by non-await.

The following code, in Doo, is an async method that returns a task, then an await call to Doo in another method test, and then calls test in the main method (because the main method does not allow Async, So you need to add an async method to use await)

static void Main (string[] args)

{

Test ();

Log ("Main: After call test");

Thread.Sleep (Timeout.infinite);

}

The main method does not allow async, so we use await in this method

static async void Test ()

{

Log ("before test:await");

await Doo ();

Log (after "test:await");

}

Async method that returns a task

Static Async Task Doo ()

{

Log ("Doo:task result:" + await task.run (() = {Thread.Sleep (+); log ("Task"); return 1;});

Log ("Doo:task result:" + await task.run (() = {Thread.Sleep (+); log ("Task"); return 2;});

Log ("Doo:task result:" + await task.run (() = {Thread.Sleep (+); log ("Task"); return 3;});

Thread.Sleep (1000);

Console.WriteLine ("Execution of Thread.Sleep outside task in doo");

}

Output method: Displays the managedthreadid of the current thread

static void log (String msg)

{

Console.WriteLine ("{0}: {1}", Thread.CurrentThread.ManagedThreadId, MSG);

}

The above code will output:

Before 1:test:await

1:main: After calling Test

3:task

3:doo:task Results: 1

4:task

4:doo:task Results: 2

3:task

3:doo:task Results: 3

Thread.Sleep execution is completed in doo outside of task

After 3:test:await

The first two sentences are simple, call the test method, the await content will be added after the target task, and then test return immediately, and then output "Main: Call Test", and they are all in the main thread execution, so managedthreadid are 1.

Then there is the execution of the other task (and, of course, another thread, the target task of the await in the test method). This so-called task is the full implementation of the Doo method. So the three sequential tasks in doo (by an await one connection) are executed sequentially, so the task output is three-to-one. The first task's managedthreadid is 3, the second is 4, and the third is 3, because the internal execution of the task uses the CLR's thread pool, so the threads are reused.

Then the doo method is not finished, and the last await causes the code behind the Doo method to continue executing after the await task is executed, and the output: Thread.Sleep execution of the task outside the doo is complete.

Finally, when Doo completely executes the await of test, it ends, so the last line output: test:await.

As I said above: The task returned by the Async method being await represents "all execution of the target async method, including the join task being split by await, but does not include multithreaded execution caused by non-await."

So if you change the Async method that returns a task (that is, the Doo method in the previous example) to this:

Async method that returns a task

Static Async Task Doo ()

{

Log ("Doo:task result:" + await task.run (() = {Thread.Sleep (+); log ("Task"); return 1;});

Log ("Doo:task result:" + await task.run (() = {Thread.Sleep (+); log ("Task"); return 2;});

Log ("Doo:task result:" + await task.run (() = {Thread.Sleep (+); log ("Task"); return 3;});

Do not use await: thread pool multithreading

ThreadPool.QueueUserWorkItem (_ =

{

Thread.Sleep (1000);

Console.WriteLine ("ThreadPool.QueueUserWorkItem");

});

Do not use Await:task multithreading

Task.run (() =

{

Thread.Sleep (1000);

Console.WriteLine ("Task.run");

});

}

We have joined multi-threaded execution without await, using ThreadPool and task separately, and the whole program will output this result:

Before 1:test:await

1:main: After calling Test

3:task

3:doo:task Results: 1

4:task

4:doo:task Results: 2

3:task

3:doo:task Results: 3

After 3:test:await

Task.run

ThreadPool.QueueUserWorkItem

Multithreading that does not use await is completely divorced from the await task in the test method and is run after the await of test.

In addition, Visual Studio warns the Task.run code as follows:



Tip: Because This awaited, execution of the current method continues before. Consider applying the ' await ' operator to the result of the call.

That is, if you do not await, the current method will continue to execute until the end, do not care about him, because we are doing in the Async method does not await the test, hehe. Www.2cto.com

You might ask, why would you want to await the task returned by another async method in this way? We've been discussing the async method of returning a task, and I think looking at an async method that returns task<t> can explain the problem better.

Next we change the above code to a similar return task<int> async method execution, then the Doo method returns TASK<T>, and he adds the results of 3 awaited tasks in his own method. The result of the task returned as the result of the return. The result returned by Doo is then output in the test method.

Full code:

static void Main (string[] args)

{

Test ();

Log ("Main: After call test");

Thread.Sleep (Timeout.infinite);

}

The main method does not allow async, so we use await in this method

static async void Test ()

{

Log ("before test:await");

Console.WriteLine ("Doo Result: {0}", await Doo ());

Log (after "test:await");

}

Async method that returns a task

Static Async task<int> Doo ()

{

var res1 = await Task.run (() = {Thread.Sleep (+); log ("awaited Task1 execute"); return

var res2 = await Task.run (() = {Thread.Sleep (+); log ("awaited Task2 execute"); return

var res3 = await Task.run (() = {Thread.Sleep (+); log ("awaited Task3 execute"); return

Do not use await: thread pool multithreading

ThreadPool.QueueUserWorkItem (_ =

{

Thread.Sleep (1000);

Console.WriteLine ("ThreadPool.QueueUserWorkItem");

});

Do not use Await:task multithreading

Task.run (() =

{

Thread.Sleep (1000);

Console.WriteLine ("Task.run");

});

Return res1 + Res2 + res3;

}

Output method: Displays the managedthreadid of the current thread

static void log (String msg)

{

Console.WriteLine ("{0}: {1}", Thread.CurrentThread.ManagedThreadId, MSG);

}

Look at the results first:

Before 1:test:await

1:main: After calling Test

3:awaited Task1 Execution

4:awaited Task2 Execution

4:awaited Task3 Execution

Doo Results: 6

After 4:test:await

ThreadPool.QueueUserWorkItem

Task.run

As in the previous example of returning a task, when the awaited task in the Task,doo returned by the await Doo method in the test method is waited for, and no awaited threads are waiting, what is this (i.e. the problem left above)? Here's an example of this return task<int>:

To await the task returned by Doo in test, we need his result at this point, and his result is to need the other awaited results contained in his own method, which can be understood as the child result of being waited. So your results need other results, so the result must wait for the results to be relied upon. So the test method await the result of the Doo method will also wait for all doo within the await, not the other doo in the non-await multi-threaded execution (of course, from a technical point of view, is not possible, because async/await can rely on the compiler).


Excerpted from MGen

. NET (C #): Await an Async method that returns a task

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.