2013-11-15 226 views
0

我有以下的異步代碼:執行異步代碼同步

public async Task<List<PreprocessingTaskResult>> Preprocess(Action onPreprocessingTaskFinished) 
{ 
    var preprocessingTasks = BuildPreprocessingTasks(); 

    var preprocessingTaskResults = new List<PreprocessingTaskResult>(); 

    while (preprocessingTasks.Count > 0) 
    { 
    //Wait till at least one task is completed 
    await TaskEx.WhenAny(preprocessingTasks.ToArray()); 

    onPreprocessingTaskFinished(); 
    } 

    return 
} 

和異步使用代碼

var preprocessingTaskResults = await Preprocess(someAction); 

在某些情況下,我需要調用它同步的方式。對於比較簡單的情況下(如異步方法只返回一個任務),我以前做到以下幾點:

var someTask = AsyncMethod(); 
Task.Wait(someTask); 

但我很困惑我應該如何在這裏實現它。

+1

最好的解決方案實際上不會創建任務,只返回一些委託並直接調用它,這可以在BuildPreprocessingTasks – Andrey

回答

3

任務的Result屬性將被阻塞,直到任務完成,然後返回它的結果:

List<PreprocessingTaskResult> result = Preprocess(someAction).Result; 

http://msdn.microsoft.com/en-us/library/dd321468(v=vs.110).aspx

+0

中完成。問題在於它經常會導致死鎖。 – svick

+0

只有在使用同步上下文的環境中時才適用。如果確實會導致死鎖,請閱讀以下內容:http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html – dcastro

1

有沒有簡單的方法來同步調用異步代碼。斯蒂芬圖博涵蓋了一些不同的方法here,但沒有辦法適用於所有情況。

最好的解決方案是將同步調用代碼更改爲異步。隨着Microsoft.Bcl.Async和最近發佈的Xamarin的出現,異步代碼現在支持.NET 4.0(及更高版本),Windows Phone 7.1(及更高版本),Windows Store,Silverlight 4(及更高版本),iOS/MonoTouch,Android/MonoDroid ,以及適用於這些平臺的任何組合的可移植類庫。

所以這幾天沒有什麼理由不是使用async

但是如果你絕對需要一個同步API,那麼最好的解決辦法就是使它一路同步。如果你確實需要異步API和同步API,這會導致代碼重複,這是不幸的,但這是目前最好的解決方案。