什么线程在 `await` 关键字之后运行代码? [英] What thread runs the code after the `await` keyword?

查看:23
本文介绍了什么线程在 `await` 关键字之后运行代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我举一个简单的例子:

Let me just post a simple example:

    private void MyMethod()
    {
        Task task = MyAsyncMethod();
        task.Wait();
    }

    private async Task MyAsyncMethod()
    {
        //Code before await
        await MyOtherAsyncMethod();
        //Code after await
    }

假设我在单线程应用程序(如控制台应用程序)中运行上述代码.我很难理解代码 //Code after await 将如何运行.

我知道当我在 MyAsyncMethod() 中点击 await 关键字时,控件会返回到 MyMethod(),但随后我锁定了线程使用 task.Wait().如果线程被锁定,如果应该使用它的线程被锁定,//Code after await 如何运行?

是否创建了一个新线程来运行 //Code after await?还是主线程神奇地跳出task.Wait() 运行//Code after await?

我不确定这应该如何工作?

Let's say I run the above code in a single threaded app -like a console app-. I'm having a difficult time understanding how the code //Code after await would be able to run.

I understand that when I hit the await keyword in MyAsyncMethod() control goes back to MyMethod(), but then I'm locking the thread with task.Wait(). If the thread is locked, how can //Code after await ever run if the thread that is supposed to take it is locked?

Does a new thread get created to run //Code after await? Or does the main thread magically steps out of task.Wait() to run //Code after await?

I'm not sure how this is supposed to work?

推荐答案

如果从主线程调用,发布的代码将在 Winform App 中死锁",因为您使用 Wait() 阻塞了主线程代码>.

Code as posted will "Deadlock" in Winform App if called from main thread because you're blocking the main thread with the Wait().

但在控制台应用程序中这是有效的.但如何?

But in console app this works. but how?

答案隐藏在 SynchronizationContext.Current 中.await 捕获SynchronizationContext",当任务完成时,它将在同一个SynchronizationContext"中继续.

Answer is hidden in the SynchronizationContext.Current. await captures the "SynchronizationContext" and when the task is completed it will continue in the same "SynchronizationContext".

在 winform 应用程序中,SynchronizationContext.Current 将设置为 WindowsFormsSynchronizationContext,它将发布到对消息循环"的调用,但谁将处理它?主线程在 Wait() 中等待.

In winform app SynchronizationContext.Current will be set to WindowsFormsSynchronizationContext which will post to the call to "Message loop", but who is going to process that? out main thread is waiting in Wait().

在控制台应用程序中,SynchronizationContext.Current 不会默认设置,因此当没有SynchronizationContext"可用于等待捕获时,它将为 null 以便安排延续到 ThreadPool(TaskScheduler.Default 是 ThreadpoolTask​​Scheduler),所以 await 之后的代码(通过线程池线程)工作.

In console app SynchronizationContext.Current will not be set by default so it will be null when no "SynchronizationContext" available for await to capture so it will schedule the continuation to ThreadPool(TaskScheduler.Default which is ThreadpoolTaskScheduler) and so the code after await works(through threadpool thread).

可以使用 Task.ConfigureAwait(false); 控制上述捕获行为,这将防止 winform 应用程序死锁,但 await 之后的代码不再在 UI 线程中运行.

Aforementioned capturing behavior can be controlled using Task.ConfigureAwait(false); which will prevent winform app from deadlocking but code after await no longer runs in UI thread.

这篇关于什么线程在 `await` 关键字之后运行代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆