【发布时间】:2016-06-12 20:10:08
【问题描述】:
我正在玩 ConfigureAwait 一点,因为我想了解它是如何工作的。
因此,我编写了以下小型控制台应用程序(实际运行在 LINQPad 中):
void Main()
{
// Use dispatcher to execute the code on STA thread
Dispatcher.CurrentDispatcher.Invoke(() => Run());
}
private async static Task Run()
{
var continueOnCapturedContext1 = true;
var continueOnCapturedContext2 = true;
PrintThreadID();
await Task.Run(() => PrintThreadID()).ConfigureAwait(continueOnCapturedContext1);
PrintThreadID();
await Task.Run(() => PrintThreadID()).ConfigureAwait(continueOnCapturedContext2);
PrintThreadID();
}
private static void PrintThreadID()
{
Console.Write(Thread.CurrentThread.ManagedThreadId.ToString("00") + "\t");
}
我得到以下输出:
A) 真/真
var continueOnCapturedContext1 = true;
var continueOnCapturedContext2 = true;
1) 11 19 11 07 11
2) 11 09 11 12 11
3) 11 06 11 06 11
预期:调度程序线程 (11) 被捕获,等待的任务在不同或相同的线程池线程上执行。
B) 假/假
var continueOnCapturedContext1 = false;
var continueOnCapturedContext2 = false;
1) 11 23 23 22 22
2) 11 19 19 19 19
3) 11 10 10 10 10
同样预期:未捕获 SynchronizationContext,因此后续可等待和不可等待代码在线程池线程上运行(通常相同)。
C) 假/真
var continueOnCapturedContext1 = false;
var continueOnCapturedContext2 = true;
1) 11 14 14 06 06
2) 11 20 20 20 20
3) 11 17 17 08 08
输出 1 和 3 的结果很奇怪。 2. awaitbale 任务是使用“在捕获的上下文中继续”选项执行的,所以我希望它与调用它的代码在同一线程上运行。
看来,如果之前已经调用过,ConfigureAwait(true/false) 对后续的等待调用没有影响,对吧?
【问题讨论】:
-
请注意,synccontext 可以为所欲为。它可以在任何线程上运行您的代码,甚至取决于硬币的翻转。因此,了解常用 上下文的作用非常重要。 ConfigureAwait(false) 只是说“即使存在也不要使用上下文”。
标签: c# async-await task-parallel-library