2012-03-03 70 views
5

我有一种方法可以对Web服务进行异步调用。类似的东西:获取异步方法的结果

public static async Task<ReturnResultClass> GetBasicResponseAsync() 
{ 
    var r = await SomeClass.StartAsyncOp(); 
    return await OtherClass.ProcessAsync(r); 
} 

我想提供同步的选择:在Result通话

public static ReturnResultClass GetBasicResponse() 
{ 
    return GetBasicResponseAsync().Result; 
} 

但它块。因为它是作为异步操作在同一个线程上调用的。我如何同步获得结果?

谢谢!

回答

8

你说得对,如果你在一个GUI应用程序中,async方法的延续部分默认在UI线程上执行。如果您同时在UI线程上执行同一个任务,您将会遇到死锁。

如果是您的应用程序,您可以通过不等待同步任务来解决此问题。

如果你只是在写一个库,你可以通过使用ConfigureAwait(false)来解决这个问题。这样,方法的继续部分将不会在捕获的上下文(GUI应用程序中的UI线程)上执行,而是在ThreadPool线程上执行。

public static async Task<ReturnResultClass> GetBasicResponseAsync() 
{ 
    var r = await SomeClass.StartAsyncOp().ConfigureAwait(false); 
    return await OtherClass.ProcessAsync(r).ConfigureAwait(false); 
} 

当然,理想的解决方案是在你的GUI应用使用ConfigureAwait()在资料库中没有使用同步操作,以便其他人可以使用的方法同步版本中,如果他们想要的。

+0

谢谢! 'ConfigureAwait'会影响我的lib的异步客户端吗?我的意思是,异步操作会保持异步,还是会针对所有客户端在其他线程上执行? – gor 2012-03-03 16:19:29

+0

是的,它也会影响异步客户端,但方式应该没问题。异步操作将保持异步,只是使用'ConfigureAwait()'的代码的延续部分不会在UI线程上执行。但是,在UI线程中启动的方法中的任何异步代码都会停留在那里(除非您也使用'ConfigureAwait()')。 – svick 2012-03-03 16:31:26