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现在从任务中提取结果,将其存储在按钮文本中,然后返回到事件循环.