任务的ConfigureAwait(False)无法正常工作

时间:2016-10-20 00:20:53

标签: vb.net

我已经阅读了很多关于等待/异步的教程,并且我已经明白,当涉及到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线程上工作。但是有一些人   声称他们是,并且也有人声称   有时任务创建线程,有时不创建。这是真的吗?

1 个答案:

答案 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)的一个主要问题是调用代码无法确定它何时完成(至少不容易)。