c# - 异步等待 : is the main thread suspended?

标签 c# async-await thread-state

我正在阅读有关 async/await 关键字的内容,我已经阅读了:

When the flow of logic reaches the await token, the calling thread is suspended until the call completes.

好吧,我创建了一个简单的 windows 窗体应用程序,放置了两个标签、一个按钮和一个文本框,然后我编写了代码:

        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";
            });            
        }

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

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

这是本书的“截图”: enter image description here

问候

最佳答案

I've read that: When the flow of logic reaches the await token, the calling thread is suspended until the call completes.

你是从哪里读到这些废话的?要么那里有一些你没有引用的上下文,要么你应该停止阅读包含它的任何文本。 await 的目的是做相反的事情。 await 的目的是在异步任务运行时保持当前线程做有用的工作

更新:我下载了您引用的那本书。该部分中的所有内容绝对是错误的。扔掉这本书,买一本更好的书。

What I don't understand is that when I click the button, the label1 will have the text Running and the label will have the same text only after 10 seconds, but in these 10 seconds I was able to enter the text in my textbox, so it seems that the main thread is running...

没错。这是发生了什么:

        label1.Text = Thread.CurrentThread.ThreadState.ToString();

文本已设置。

        button1.Text =  await DoWork();

这里发生了很多事情。首先会发生什么? DoWork 被调用。它有什么作用?

        return Task.Run(() => { Thread.Sleep(10000);

它从线程池中抓取一个线程,让该线程休眠十秒钟,然后返回一个表示该线程正在完成的“工作”的任务。

现在我们回到这里:

        button1.Text =  await DoWork();

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

嘿,它的调用者是什么?无论如何,我们是怎么到这里的?

一些代码调用了这个事件处理程序;处理 Windows 消息的是事件循环。它看到一个按钮被点击并被分派(dispatch)给刚刚返回的点击处理程序。

现在发生了什么?事件循环继续运行。正如您所注意到的,您的 UI 一直运行良好。最终该线程结束 10 秒,任务的继续被激活。那有什么作用?

这会将一条消息发布到 Windows 队列中,指出“您现在需要运行该事件处理程序的其余部分;我有您要查找的结果。”

主线程事件循环最终得到该消息。所以事件处理程序从它停止的地方开始:

        button1.Text =  await DoWork();

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

关于c# - 异步等待 : is the main thread suspended?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37667499/

相关文章:

c# - 如何从其 valueMember 设置组合框基的选定索引? (C# 窗口窗体)

struts2 - NPE为什么会导致JVM崩溃?

Java 监听线程状态

c# - Azure 函数 - function.json 它位于何处?

c# - 无效的 Switch 语法构建成功了吗?

c# - 提高 DataTable.Load() 性能的方法?

javascript - 为什么不在 MVC 应用程序中的所有操作上使用异步?

c# - 如何 "await"关闭另一个窗口

c# 5 异步作为糖语法(或不是)?

"waiting on condition"的java线程转储意义