【问题标题】:How to call async method asynchronously from non-async method如何从非异步方法异步调用异步方法
【发布时间】:2013-02-27 06:21:54
【问题描述】:

如何在非异步方法中等待来自异步方法的任务,而不实际调用该方法?

Class TestAsync
    Dim workevent As New Threading.ManualResetEvent(False)
    Sub work()
        Dim Task As Task = Test()
        'Do Work which affects Test Here
        Threading.Thread.Sleep(100)
        workevent.Set()
        'wait for Test to complete
        'Task.Wait() -causes the application to hang
    End Sub

    Async Function Test() As Task
        workevent.WaitOne()
    End Function
End Class

【问题讨论】:

    标签: vb.net async-await


    【解决方案1】:

    首先,如果可能,永远不要那样做。同步等待异步方法破坏了使用异步的全部目的。相反,您应该将work() 变成Async Function WorkAsync() As Task。然后将调用work() 的方法也设为异步,以此类推,一直向上。

    其次,异步与并行不同。如果您有Async 方法而没有Awaits,它将完全同步执行,就好像它是一个普通方法一样。因此,即使没有Task.Wait(),您的方法也会挂起。

    你可以做的是使用Task.Run()在后台线程上运行Test()

    Sub work()
        Dim Task As Task = Task.Run(AddressOf Test)
        Threading.Thread.Sleep(100)
        workevent.Set()
        Task.Wait()
    End Sub
    

    Run() 返回的Task 将在从Test() 返回的Task 完成时完成。

    (在组合Wait()Async 时,还有其他问题会导致挂起,但它们与此特定情况无关。)

    但我再说一遍:你不应该这样做,因为它会阻塞 UI 线程,尽管它只是一小会儿。

    【讨论】:

    • 这个函数正在单元测试中运行,所以它必须在某处停止异步
    • @user1937198 如果您的单元测试框架支持Async,它不会。 .Net 的大多数单元测试框架的当前版本都可以。
    • +1。当前版本的 MSTest、xUnit 和 NUnit 都支持返回 Taskasync 单元测试方法。
    • 不是VS2012自带的MSTest
    • 2012 版 2 ctp 3,mstest 可以单独升级吗?
    猜你喜欢
    • 2017-03-06
    • 1970-01-01
    • 2016-07-20
    • 2020-03-10
    • 1970-01-01
    • 2021-04-18
    • 1970-01-01
    相关资源
    最近更新 更多