我正在阅读有关 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 是如何工作的?
问候
最佳答案
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/