by default the await operator will capture the current "context" and use that to resume the async method.
我正在我的控制台应用程序中尝试这段代码:
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
为什么?还有如果我想在 await 之后使用同一个线程,我应该如何设置同步上下文?
最佳答案
Why?
新的 SynchronizationContext()
by convention与 null
SynchronizationContext
相同。 “无 SyncCtx”和“默认 SyncCtx”都只是将工作排队到线程池。
SynchronizationContext
与特定线程之间不是 1:1 的关系。例如:
- WinForms UI
SynchronizationContext
会将工作排队到单个 UI 线程。据我所知,WinFormsSynchronizationContext
是单例,因此在这种情况下有一个 1:1 映射。 - WPF
SynchronizationContext
会将工作排队到其Dispatcher
。上次我检查时,WPF 将为每个顶级窗口创建一个新的实例,即使它们都使用相同的线程。所以有一个N:1映射。 - 线程池(默认/
null
)SynchronizationContext
可以将工作排队到任何线程池线程。如果您不创建默认的SynchronizationContext
实例,则存在 1:N 映射。
And also how I should set sync context if I want to use the same thread after await?
您需要使用自定义 SynchronizationContext
。我建议使用我的 AsyncContext
or AsyncContextThread
types ,因为这不是编写简单的代码。
关于c# - 为什么同步上下文不适用于等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44067947/