我已经阅读了很多关于async-await模式的文章,但我仍然不确定是否在UI线程上运行异步方法(等待的方法)。 我总是最终使用SynchronizationContext类“异步方法在与被调用者相同的SynchronizationContext中运行”这究竟意味着什么?
是新创建的单独线程(我知道它不是)还是ThreadPool线程?
当我读取SynchronizationContext时,我发现它是某种排队的任务执行者,但这些任务在哪里执行?在ThreadPool上?
如果是,则在ThreadPool上执行异步方法,对吗?
答案 0 :(得分:4)
标记为async
的方法在调用它的线程上运行,直到它到达其中的第一个await
关键字。
但有一个例外:如果等待的方法在到达await
关键字时已经完成运行,那么执行只会在不切换线程的情况下继续执行。
public async Task Method()
{
Console.WriteLine(1);
await Something();
Console.Writeline(2);
}
在这种情况下,如果在线程A上调用该方法,则也将从线程A打印1。
然后你转到下一条指令。
如果Task
返回的something
已经完成,则在线程A上继续执行。
如果Task
返回的something
仍在运行,则可以从以下任一位置打印出来:
关于你对ThreadPool的怀疑:
正如我们所见,async
方法不能保证在ThreadPool上运行。
只有Task.Run
重载方法之一安排的工作肯定会在ThreadPool上运行。
引用Task
MSDN doc:
将指定的工作排队到ThreadPool上并返回该工作的任务句柄。
public void Task Something()
{
return Task.Run(() => Console.WriteLine(3));
}
3将由ThreadPool上的一个线程打印。
答案 1 :(得分:3)
我已经阅读了很多关于async-await模式的文章,但我仍然不确定异步方法(等待的方法)是否在UI线程上运行。
如果您还没有,请查看我的async
intro post,其中解释了async
和await
的线索行为。
当您调用async
方法时,它会在第一次await
未完成的操作时同步执行。然后async
方法捕获当前的“上下文”并调度其余部分以便稍后执行,然后返回。
稍后,当操作完成时,async
方法的其余部分将安排在捕获的“上下文”上运行。
“上下文”是当前SynchronizationContext
,除非它是null
,在这种情况下,它是当前TaskScheduler
。当您从UI线程调用async
方法时,您有一个UI SynchronizationContext
,它通过将工作发布到UI线程的消息循环来工作。