2012-03-03 69 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