async await:是主线程被挂起了吗?

Bud*_*ril 7 c# thread-state async-await

我正在阅读关于async/await关键字的内容,我读到了:

当逻辑流到达等待令牌时,调用线程将暂停,直到调用完成.

好吧,我创建了一个简单的windows forms application,放置了两个标签,一个按钮和一个文本框,我编写了代码:

        private async void button1_Click(object sender, EventArgs e)
        {
            label1.Text = Thread.CurrentThread.ThreadState.ToString();
            button1.Text =  await DoWork();
            label2.Text = Thread.CurrentThread.ThreadState.ToString();
        }

        private Task<string> DoWork()
        {
            return Task.Run(() => {
                Thread.Sleep(10000);
                return "done with work";
            });            
        }
Run Code Online (Sandbox Code Playgroud)

我不明白的是,当我点击按钮时,label1将有文本Running,标签将在10秒后只有相同的文字,但在这10秒钟内,我能够在文本框中输入文字,所以看来主线程正在运行......

那么,async/await是如何工作的呢?

这是书中的"截图": 在此输入图像描述

问候

Eri*_*ert 19

我已经读过:当逻辑流到达等待令牌时,调用线程被挂起,直到调用完成.

你在哪里读到那些废话?在那里有一些你没有引用的上下文,或者你应该停止阅读包含它的任何文本.等待的目的是做相反的事情.等待的目的是在异步任务正在进行时保持当前线程执行有用的工作.

更新:我下载了你引用的书.绝对是该部分的一切都是错误的.扔掉这本书,买一本更好的书.

我不明白的是,当我点击按钮时,label1将有文本Running并且标签将在10秒后具有相同的文本,但是在这10秒内我能够在我的文本框中输入文本,所以似乎主线程正在运行......

那是对的.这是发生的事情:

        label1.Text = Thread.CurrentThread.ThreadState.ToString();
Run Code Online (Sandbox Code Playgroud)

文本已设置.

        button1.Text =  await DoWork();
Run Code Online (Sandbox Code Playgroud)

这里发生了一堆事情.先发生什么事? DoWork叫做.它有什么作用?

        return Task.Run(() => { Thread.Sleep(10000);
Run Code Online (Sandbox Code Playgroud)

它从线程池中抓取一个线程,将该线程置于休眠状态十秒钟,然后返回一个表示该线程正在完成的"工作"的任务.

现在我们回到这里:

        button1.Text =  await DoWork();
Run Code Online (Sandbox Code Playgroud)

我们手头有一项任务.Await首先检查任务是否已完成.它不是.接下来,它将此方法的其余部分注册为任务的继续.然后它返回其调用者.

嘿,它的来电是什么?我们怎么到这儿了?

一些代码称为此事件处理程序; 它是处理Windows消息的事件循环.它看到一个按钮被点击并被分派到刚刚返回的点击处理程序.

现在发生了什么?事件循环继续运行.正如您所注意到的,您的UI保持良好的运行状态.最终该线程退出10秒并激活任务的继续.那是做什么的?

这会在Windows队列中发布一条消息,说"你需要立即运行该事件处理程序的其余部分;我有你正在寻找的结果."

主线程事件循环最终会到达该消息.所以事件处理程序会从中断处继续:

        button1.Text =  await DoWork();
Run Code Online (Sandbox Code Playgroud)

await现在从任务中提取结果,将其存储在按钮文本中,然后返回到事件循环.

  • @BudaGavril:关于async-await的部分从头到尾完全错误地完成了这本书.作者完全误解了它.扔掉这本书,得到一本更好的书. (6认同)