这个答案 https://stackoverflow.com/a/21839382/2631076 says
默认情况下,await 运算符将捕获当前“上下文”并使用它来恢复异步方法。
我正在我的控制台应用程序中尝试此代码:
static void Main(string[] args)
{
Test().Wait();
}
private static async Task Test()
{
var context = new SynchronizationContext();
SynchronizationContext.SetSynchronizationContext(context);
Console.WriteLine("Thread before: " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(await GetResultAsync());
Console.WriteLine("Thread after: " + Thread.CurrentThread.ManagedThreadId);
}
private static async Task<string> GetResultAsync()
{
return await Task.Factory.StartNew(() =>
{
Console.WriteLine("Thread inside: " + Thread.CurrentThread.ManagedThreadId);
return "Hello stackoverflow!";
});
}
...然后把这个拿出来:
Thread before: 1
Thread inside: 3
Hello stackoverflow!
Thread after: 3
为什么?如果我想在等待后使用相同的线程,我应该如何设置同步上下文?
Why?
new SynchronizationContext()
按照惯例 https://msdn.microsoft.com/en-us/magazine/gg598924.aspx与 a 相同null
SynchronizationContext
。 “no SyncCtx”和“default SyncCtx”都只是将工作排队到线程池。
之间不存在 1:1 的关系SynchronizationContext
和一个特定的线程。例如:
- WinForms 用户界面
SynchronizationContext
将把工作排队到单个 UI 线程。 AFAIK,WinFormsSynchronizationContext
是单例,所以存在1:1映射在这种情况下.
- The WPF
SynchronizationContext
将工作排队到其Dispatcher
。上次我检查时,WPF 将创建一个新的instance对于每个顶级窗口,即使它们都使用相同的线程。所以存在N:1映射。
- 线程池(默认/
null
) SynchronizationContext
可以将工作排队到任何线程池线程。如果您不创建默认值SynchronizationContext
例如,存在 1:N 映射。
如果我想在等待后使用相同的线程,我应该如何设置同步上下文?
您需要使用自定义的SynchronizationContext
。我建议使用我的AsyncContext or AsyncContextThread types https://github.com/StephenCleary/AsyncEx,因为这不是编写简单的代码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)