如何以及何时使用“async"和“await" [英] How and when to use ‘async’ and ‘await’

查看:29
本文介绍了如何以及何时使用“async"和“await"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据我的理解,asyncawait 是为了让代码易于编写和阅读——但是使用它们是否等于产生后台线程来执行长时间的逻辑?

From my understanding one of the main things that async and await do is to make code easy to write and read - but is using them equal to spawning background threads to perform long duration logic?

我目前正在尝试最基本的示例.我已经内联添加了一些评论.你能帮我澄清一下吗?

I'm currently trying out the most basic example. I've added some comments inline. Can you clarify it for me?

// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
    Task<int> access = DoSomethingAsync();
    // task independent stuff here

    // this line is reached after the 5 seconds sleep from 
    // DoSomethingAsync() method. Shouldn't it be reached immediately? 
    int a = 1; 

    // from my understanding the waiting should be done here.
    int x = await access; 
}

async Task<int> DoSomethingAsync()
{
    // is this executed on a background thread?
    System.Threading.Thread.Sleep(5000);
    return 1;
}

推荐答案

当使用 asyncawait 时,编译器会在后台生成一个状态机.

When using async and await the compiler generates a state machine in the background.

这是一个例子,我希望我可以解释一些正在发生的高级细节:

Here's an example on which I hope I can explain some of the high-level details that are going on:

public async Task MyMethodAsync()
{
    Task<int> longRunningTask = LongRunningOperationAsync();
    // independent work which doesn't need the result of LongRunningOperationAsync can be done here

    //and now we call await on the task 
    int result = await longRunningTask;
    //use the result 
    Console.WriteLine(result);
}

public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation 
{
    await Task.Delay(1000); // 1 second delay
    return 1;
}

好的,那么这里发生了什么:

OK, so what happens here:

  1. TasklongRunningTask = LongRunningOperationAsync(); 开始执行LongRunningOperation

独立工作完成,让我们假设主线程(线程 ID = 1)然后到达 await longRunningTask.

Independent work is done on let's assume the Main Thread (Thread ID = 1) then await longRunningTask is reached.

现在,如果longRunningTask还没有完成并且还在运行,MyMethodAsync()会返回到它的调用方法,这样主线程就不会得到阻止.当 longRunningTask 完成后,来自 ThreadPool 的线程(可以是任何线程)将返回到其先前上下文中的 MyMethodAsync() 并继续执行(在这种情况下打印结果到控制台).

Now, if the longRunningTask hasn't finished and it is still running, MyMethodAsync() will return to its calling method, thus the main thread doesn't get blocked. When the longRunningTask is done then a thread from the ThreadPool (can be any thread) will return to MyMethodAsync() in its previous context and continue execution (in this case printing the result to the console).

第二种情况是 longRunningTask 已经完成执行并且结果可用.当到达 await longRunningTask 时,我们已经有了结果,所以代码将继续在同一个线程上执行.(在这种情况下,将结果打印到控制台).当然,上面的例子不是这种情况,其中涉及到 Task.Delay(1000).

A second case would be that the longRunningTask has already finished its execution and the result is available. When reaching the await longRunningTask we already have the result so the code will continue executing on the very same thread. (in this case printing result to console). Of course this is not the case for the above example, where there's a Task.Delay(1000) involved.

这篇关于如何以及何时使用“async"和“await"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆