ror*_*.ap 1 .net vb.net asynchronous async-await
我有这个代码:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim t = DoStuffAsync()
t.Wait()
Debug.Print(t.Result)
End Sub
Private Async Function DoStuffAsync() As Task(Of String)
Await Task.Delay(2000)
Return "Stuff"
End Function
Run Code Online (Sandbox Code Playgroud)
我知道这不是正确的做法.以下是我认为可能正确的方法:
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim t = DoStuffAsync()
Debug.Print(Await t)
End Sub
Private Async Function DoStuffAsync() As Task(Of String)
Await Task.Delay(2000)
Return "Stuff"
End Function
Run Code Online (Sandbox Code Playgroud)
我只是想知道,t.Wait()当我运行第一个代码示例时,为什么它会无限期地挂起?什么恰好是发生在代码执行在这一点上,即什么代码是"运行",当线程被阻塞的t.Wait()?
让我们首先考虑实用性:是的,你应该Await而不是Wait()结果.现在谈谈你为什么会这样做的问题......
在Stephen Cleary的博客文章Do not Block on Async Code中,他解释了这是如何发生的.这是他的"发生了什么"演练,修改为您的方法:
Button1_Click调用DoStuffAsync(在UI上下文中).DoStuffAsync调用Task.Delay(仍然在上下文中).Task.Delay 返回未完成的任务,指示时间尚未过去.DoStuffAsync等待Task归来的Task.Delay.捕获上下文并将用于DoStuffAsync稍后继续运行该方法.DoStuffAsync返回未完成Task,表示DoStuffAsync方法未完成.Task返回的DoStuffAsync.这会阻止上下文线程.Delay任务将完成.DoStuffAsync现在已经准备好运行,它等待的情况下可用,因此它可以在上下文中执行的.DoStuffAsync完成,并DoStuffAsync等待上下文空闲,以便它可以完成.在这个UI上下文中,这也恰好是一个特定的线程,但这不一定是强制转换.例如,在ASP.NET中,有一个可以在任何线程上运行的上下文,但一次只能在一个线程上运行.重要的是上下文被锁定,无论它实际运行的是什么线程.