Await and await threads

Source: Internet
Author: User

Await and await threads

I read an article in the garden, "the past and present of async & await", with a lot of benefits. Some of these statements are marked in red by the blogger, so I read a few more points. "await will not start a new thread (await will never start a new thread )」. The relevant information found on MSDN also proves its correctness-The async and await keywords don't cause additional threads to be created. async methods don't require multithreading because an async method doesn' t run on its own thread. the method runs on the current synchronization context and uses time on the thread only when the method is active. (async and await keywords do not cause other threads to be created. Because the asynchronous method does not run on its own thread, it does not need multithreading. Only when the method is active, the method runs in the current synchronization context and uses the time on the thread .)

Create a Windows Forms Application project and write some code to better illustrate the problem:

private void Form1_Load(object sender, EventArgs e){    PrintDataAsync();    Debug.Print("three");}private async void PrintDataAsync(){    Task<int> result = CalculateDataAsync();    Debug.Print("second");    int data = await result;    Debug.Print("last:" + data);}private async Task<int> CalculateDataAsync(){    Debug.Print(string.Format("{0} : {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));    Debug.Print("first");    int result = 0;    for (int i = 0; i < 10; i++)    {        result += i;    }    await Task.Delay(1000);    Debug.Print("four");    Debug.Print(string.Format("{0} : {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));    return result;};

The program results are as expected. The Output window shows the following content:

8 : Falsefirstsecondthreefour8 : Falselast:45

The value of ManagedThreadId before await is the same as the value of ManagedThreadId after await. The value of IsThreadPoolThread is always False, indicating that the current thread has not changed and no new thread has been generated.

However, if you create a Console application project, the results will be different.

static void Main(string[] args){    PrintDataAsync();    Console.WriteLine("three");    Console.Read();}private static async void PrintDataAsync(){    Task<int> result = CalculateDataAsync();    Console.WriteLine("second");    int data = await result;    Console.WriteLine("last:" + data);}private static async Task<int> CalculateDataAsync(){    Console.WriteLine(string.Format("{0} : {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));    Console.WriteLine("first");    int result = 0;    for (int i = 0; i < 10; i++)    {        result += i;    }    await Task.Delay(1000);    Console.WriteLine("four");    Console.WriteLine(string.Format("{0} : {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));    return result;}

Execution result of this Code:

8 : Falsefirstsecondthreefour10 : Truelast:45

ManagedThreadId changes after await, and IsThreadPoolThread also changes to True, indicating that it is not the same thread.

Why? Let's take a look at The description in MSDN -- "the method runs on the current synchronization context and uses time on the thread only when The method is active", which involves the use of the SynchronizationContext object.

Add Debug. Print (SynchronizationContext. Current. ToString () to the Windows Forms project code, and check the code. The output is System. Windows. Forms. WindowsFormsSynchronizationContext.

If a similar detection code Console is added to the Console project. writeLine (SynchronizationContext. current. toString (); will throw an empty reference exception because SynchronizationContext. the value of Current in the Console project is null.

Also, find the articles related to SynchronizationContext from MSDN Magazine, including: By convention, if a thread's current SynchronizationContext is null, then it implicitly has a default SynchronizationContext. (By convention, if the current SynchronizationContext of a thread is null, it has a default SynchronizationContext .) The default SynchronizationContext is applied to ThreadPool threads unless the code is hosted by ASP. NET. (by default, SynchronizationContext is applied to ThreadPool threads unless The code is carried by ASP. NET .)

APS. NET is mentioned here, so another Web Forms Application project is created for verification:

protected void Page_Load(object sender, EventArgs e){    PrintDataAsync();    Debug.Print("three");}private async void PrintDataAsync(){    Debug.Print(SynchronizationContext.Current.ToString());    Task<int> result = CalculateDataAsync();    Debug.Print("second");    int data = await result;    Debug.Print("last:" + data);}private async Task<int> CalculateDataAsync(){    Debug.Print(string.Format("{0} : {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));    Debug.Print("first");    int result = 0;    for (int i = 0; i < 10; i++)    {        result += i;    }    await Task.Delay(1000);    Debug.Print("four");    Debug.Print(string.Format("{0} : {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));    return result;}

Output result:

System.Web.AspNetSynchronizationContext8 : Truefirstsecondthreefour9 : Truelast:45

The value of ManagedThreadId is changed. The value of IsThreadPoolThread is always True, and the value of SynchronizationContext. Current is System. Web. AspNetSynchronizationContext.

Based on three experiments and relevant data, we can conclude that the threads after await produce different results based on different definitions of SynchronizationContext in different environments. So the "await will not start a new thread (await will never start a new thread)" must be changed to "will it start a new thread after await? Maybe is more appropriate.

Finally, if the code for the first Windows Forms project is await Task. delay (1000); changed to await Task. delay( 1000 ). configureAwait (false);, you can get the same result of the second Console project.

 


In java multithreading, what is the difference between await and wait?

In fact, the usage of await is similar to that of wait. Await is improved by wait. Now await is used for more than half of development, because await adds the lock method.
Lock replaces the use of synchronized methods and statements.

[Beginner] c # asynchronous programming. Why is the page stuck when await is used?

These operations are still sent to the UI thread for execution.
Await can be understood as the CallBack in. NET 4: when the task ends, a completion event is triggered. The purpose of await is to run the Code marked by await after the completion event is triggered. It should not affect the UI card or card.
Try to call LetFeedShowAsync (int index) by another thread to see if it can solve your problem.

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.