我已经阅读了很多关于等待/异步的教程,并且我已经明白,当涉及到await
关键字时,它会回到main context
然后去返回await
(完成后),如果在away
方法async
之后出现问题,请继续进一步继续。我还读到有ConfigureAwait(False)
之类的东西,只是意味着与await
之前写的相反,此时它不会回到main context
但是会留在这里并等待await
完成,然后继续async
方法,之后将返回main cotext
。所以差异是它不会回到main context
而是等待await
。如果我错了,请纠正。根据第一个例子中的知识,我应该看到以下结果:
After DoStafAsync
Done running the long operation asynchronously.
但是当我只是添加ConfigureAwait(False)时,它应该是:
Done running the long operation asynchronously.
After DoStafAsync
因为它不会返回上下文但会等待并在异步方法完成之后再返回。不知怎的,我在第一个输出中看到了结果。我错过了什么?
Public Class Form1
Sub LongOperation()
Threading.Thread.Sleep(5000)
End Sub
Private Async Function DoStafAsync() As Task
lblStatus.Text = "Running a long operation asynchronously... (UI thread should be fully responsive)"
Await Task.Run(Sub()
LongOperation()
End Sub).ConfigureAwait(False)
lblStatus.Text = "Done running the long operation asynchronously."
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
dfg
lblStatus.Text = "After DoStafAsync"
End Sub
Async Sub Dfg
Await DoStafAsync
End Sub
End Class
其他问题:有些人声称任务没有创建 线程但在同一个ui线程上工作。但是有一些人 声称他们是,并且也有人声称 有时任务创建线程,有时不创建。这是真的吗?
答案 0 :(得分:0)
我已经明白,当涉及到await关键字时,它将返回到主要上下文然后返回等待(当它完成时)然后继续进一步,如果在异步方法之后有一些东西。
我不认为你在解释异步代码时通常使用的术语“上下文”。查看我的async
intro blog post,它可以准确说明上下文是什么以及await
如何使用它。
特别是,“上下文”不表示“方法或功能”。它不确定代码如何或何时返回到代码的另一部分。
您可能还想阅读我的MSDN article on async best practices,这解释了为什么您应该避免异步void(事件处理程序除外)。如果你使Form1_Load
成为异步空格并摆脱dfg
,那么它就像你期望的那样工作:
Private Async Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Await DoStafAsync
lblStatus.Text = "After DoStafAsync"
End Sub
之前没有工作的原因是因为Form1_Load
没有等待dfg
(或DoStafAsync
)完成 - 它只是将它们关闭然后立即进行设置标签文字。正如我在最佳实践文章中指出的那样,async void(async sub)的一个主要问题是调用代码无法确定它何时完成(至少不容易)。