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

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

// 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 时,编译器会在后台生成一个状态机。
这是一个例子,我希望我可以解释一些正在发生的高级细节:

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;
}
好的,那么这里会发生什么:
  • Task<int> longRunningTask = LongRunningOperationAsync(); 开始执行 LongRunningOperation
  • 独立工作已完成,假设主线程(线程 ID = 1)然后到达 await longRunningTask
    现在,如果 longRunningTask 还没有完成并且它仍在运行,则 MyMethodAsync() 将返回其调用方法,因此主线程不会被阻塞。当 longRunningTask 完成时,来自 ThreadPool 的线程(可以是任何线程)将返回到其先前上下文中的 MyMethodAsync() 并继续执行(在这种情况下将结果打印到控制台)。

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

    关于c# - 如何以及何时使用 ‘async’ 和 ‘await’,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14455293/

    10-13 03:14