2013-02-26 317 views
1

如何在不实际调用方法的情况下等待来自异步方法的异步方法中的任务?如何从非异步方法异步调用异步方法

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 

回答

2

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

二,异步并行不一样。如果你有Async方法没有Await s,它将完全同步执行,就好像它是一个正常的方法。所以,即使没有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 

TaskRun()返回将完成从何时完成Test()返回Task

(有引起挂起结合Wait()Async当其他的问题,但他们不是在这个特定的情况下,相关的。)

但我重申:你不应该这样做,因为它会阻止UI线程,虽然只是短暂的。

+0

此函数正在单元测试中运行,所以它必须停止异步 – user1937198 2013-02-26 22:23:06

+0

@ user1937198它不,如果你的单元测试框架支持'异步'。目前版本的大多数.Net单元测试框架都可以。 – svick 2013-02-26 22:24:24

+0

+1。当前版本的MSTest,xUnit和NUnit都支持返回Task的'async'单元测试方法。 – 2013-02-27 01:42:34