我以为我理解异步/等待,但显然不是。我有这样的事情:
public async void SomeEventHandler()
{
await Task.Run(() => Method1());
}
private async Task Method1()
{
// Running on a worker thread here.
await SomeOtherMethodAsync();
// Now running on the UI thread.
}正如您从上面的注释中可以看到的那样,Method1从您期望的在b/g线程上运行开始,并使用了Task.Run()进行调用。但是,在第一个await之后,剩下的代码将在UI线程上运行。我相信将ConfigureAwait(false)添加到“内部”异步方法调用中将防止这种情况发生,但我不明白为什么它首先在UI线程上恢复。为什么UI线程而不是原始(或其他) b/g线程?
当然,“默认”恢复UI线程是适得其反的,因为有可能阻止UI,这正是异步/等待所试图避免的。
在我的实际代码中,Method1做了很多与CPU绑定的事情,因此我使用Task.Run调用它;该方法还调用了许多异步I/O绑定方法。我在使用异步/等待和Task.Run时是否采取了正确的方法?
编辑只是为了澄清,我在Method1和线程窗口中使用了断点,以查看代码在哪个线程上运行。在awaitable方法调用之前,thread窗口突出显示一个工作线程,而在awaitable方法调用之后,“主线程”被高亮显示。
Edit2在下面回答@Aly的问题时,使用相同的调试文本,如下所示:
ManagedThreadID (Dispatcher): 11
ManagedThreadID (MainThread - before Task.Run(Method1)): 11
ManagedThreadID (Method1 - before SomeOtherMethodAsync): 14
ManagedThreadID (SomeOtherMethodAsync): 14
ManagedThreadID (Method1 - after SomeOtherMethodAsync): 11
ManagedThreadID (MainThread - after Task.Run(Method1)): 18发布于 2019-02-20 13:21:31
就像@canton7在评论中指出的那样,我刚刚测试了WPF应用程序提供的代码,您描述的行为似乎并不存在。
我的测试:
public async void SomeEventHandler()
{
Debug.WriteLine($"ManagedThreadID (Dispatcher): {Dispatcher.CurrentDispatcher.Thread.ManagedThreadId}");
Debug.WriteLine($"ManagedThreadID (MainThread - before Task.Run(Method1)): {Thread.CurrentThread.ManagedThreadId}");
await Task.Run(() => Method1());
Debug.WriteLine($"ManagedThreadID (MainThread - after Task.Run(Method1)): {Thread.CurrentThread.ManagedThreadId}");
}
private static async Task Method1()
{
Debug.WriteLine($"ManagedThreadID (Method1 - before SomeOtherMethodAsync): {Thread.CurrentThread.ManagedThreadId}");
await SomeOtherMethodAsync();
Debug.WriteLine($"ManagedThreadID (Method1 - after SomeOtherMethodAsync): {Thread.CurrentThread.ManagedThreadId}");
}
private static Task SomeOtherMethodAsync()
{
Debug.WriteLine($"ManagedThreadID (SomeOtherMethodAsync): {Thread.CurrentThread.ManagedThreadId}");
return Task.Delay(1000);
}调试输出:
ManagedThreadID (Dispatcher): 1
ManagedThreadID (MainThread - before Task.Run(Method1)): 1
ManagedThreadID (Method1 - before SomeOtherMethodAsync): 3
ManagedThreadID (SomeOtherMethodAsync): 3
ManagedThreadID (Method1 - after SomeOtherMethodAsync): 3
ManagedThreadID (MainThread - after Task.Run(Method1)): 1https://stackoverflow.com/questions/54786648
复制相似问题