首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么异步/等待恢复在UI线程上?

为什么异步/等待恢复在UI线程上?
EN

Stack Overflow用户
提问于 2019-02-20 12:42:16
回答 1查看 443关注 0票数 0

我以为我理解异步/等待,但显然不是。我有这样的事情:

代码语言:javascript
复制
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的问题时,使用相同的调试文本,如下所示:

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2019-02-20 13:21:31

就像@canton7在评论中指出的那样,我刚刚测试了WPF应用程序提供的代码,您描述的行为似乎并不存在。

我的测试:

代码语言:javascript
复制
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);
}

调试输出:

代码语言:javascript
复制
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)): 1
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54786648

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档