c# - 如何以及何时使用 ‘async’ 和 ‘await’

标签 c# .net asynchronous async-await

根据我的理解,其中一件主要事情是 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;
}

最佳答案

使用 async 时和 await编译器在后台生成一个状态机。

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

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完成后,ThreadPool 中的一个线程(可以是任何线程)将返回到 MyMethodAsync()在其先前的上下文中并继续执行(在本例中将结果打印到控制台)。

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

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

相关文章:

c# - 泛型 Func<T> 的运行时创建

.Net BindingDictionary

c# - 具有异步静态方法的最小 API

java - 使用 cucumber-jvm 异步执行步骤

c# - 在 ASP.NET Core 应用程序中临时存储数据

c# - 尝试设置本地计算机帐户密码时出现未知错误 (0x80005000)

c# - FoxPro 到 C# : What best method between ODBC, OLE DB 或其他?

c# - 同一解决方案中的不同 EntityFramework 版本

reactjs - 为什么我们应该避免组件构造函数中的副作用?

c# - 如何将对撞机添加到复杂的迷宫