'等待'任务在哪里执行?

Eri*_*ric 6 c# multithreading asynchronous task-parallel-library async-await

考虑以下:

private async void btnSlowPoke_Click(object sender, EventArgs e)
{
    await DoItAsync();
}

private async Task<int> SomeLongJobAsync()
{
    for (int x = 0; x < 999999; x++)
    {
        //ponder my existence for one second
        await Task.Delay(1000);
    }
    return 42;
}

public async Task<int> DoItAsync()
{
    Console.Write("She'll be coming round the mountain");
    Task<int> t = SomeLongJobAsync();  //<--On what thread does this execute?
    Console.WriteLine(" when she comes.");
    return await t;
}
Run Code Online (Sandbox Code Playgroud)
  1. 第一个写入DoItAsync()执行.
  2. SomeLongJobAsync() 开始.
  3. WriteLineDoItAsync()执行.
  4. DoItAsync()SomeLongJobAsync()工作之前暂停,直到完成.
  5. SomeLongJobAsync()完成,所以DoItAsync()返回.

同时,UI响应迅速.

什么线程SomeLongJobAsync()执行?

i3a*_*non 9

简答

每当执行CPU操作时async,GUI线程触发的方法将在同一线程执行.其他async方法开始在调用线程上运行并继续在ThreadPool线程上.

答案很长

SomeLongJobAsync开始在调用线程(打印"她将要绕山")上执行,直到它到达await.然后返回一个表示异步操作+之后的继续的任务.当整个操作完成任务将完成(除非它提前完成因异常或取消).

Task.Delay(1000)它自己"执行"时,没有线程,因为不需要线程.最后,当Task.Delay(1000)结束时,线程需要恢复上.它取决于哪个线程SynchronizationContext(默认情况下没有,所以线程是一个ThreadPool线程,但在GUI应用程序中它是单个GUI线程,更多这里).该线程执行代码的其余部分,直到它到达另一个异步点(即另一个await),依此类推.