一尘不染

如何以及何时使用“异步”和“等待”

c#

根据我的理解asyncawait要做的主要事情之一就是使代码易于编写和阅读-但是使用它们是否等同于产生后台线程来执行长时间逻辑?

我目前正在尝试最基本的示例。我在行中添加了一些评论。你能为我澄清一下吗?

// 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;
}

阅读 205

收藏
2020-05-19

共1个答案

一尘不染

使用时asyncawait编译器会在后台生成状态机。

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

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;
}

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

  1. Task<int> longRunningTask = LongRunningOperationAsync(); 开始执行 LongRunningOperation

  2. 假设已经到达主线程(线程ID = 1),就完成了独立的工作await longRunningTask

现在,如果longRunningTask尚未完成并且仍在运行,MyMethodAsync()将返回其调用方法,因此主线程不会被阻塞。当longRunningTask随后完成从线程池线程(可以是任何线程)将返回MyMethodAsync()其先前的背景下,继续执行(在这种情况下,打印结果到控制台)。

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

2020-05-19