我有一些代碼,當被調用時調用Web服務,查詢數據庫並從本地緩存中獲取一個值。然後它將這三個行爲的返回值結合起來以產生結果。我不想按順序執行這些操作,而是希望以並行方式異步執行它們。下面是一些僞/示例代碼:c#線程異步問題
var waitHandles = new List<WaitHandle>();
var wsResult = 0;
Func<int> callWebService = CallWebService;
var wsAsyncResult = callWebService.BeginInvoke(res => { wsResult = callWebService.EndInvoke(res); }, null);
waitHandles.Add(wsAsyncResult.AsyncWaitHandle);
string dbResult = null;
Func<string> queryDB = QueryDB;
var dbAsyncResult = queryDB.BeginInvoke(res => { dbResult = queryDB.EndInvoke(res); }, null);
waitHandles.Add(dbAsyncResult.AsyncWaitHandle);
var cacheResult = "";
Func<string> queryLocalCache = QueryLocalCache;
var cacheAsyncResult = queryLocalCache.BeginInvoke(res => { cacheResult = queryLocalCache.EndInvoke(res); }, null);
waitHandles.Add(cacheAsyncResult.AsyncWaitHandle);
WaitHandle.WaitAll(waitHandles.ToArray());
Console.WriteLine(string.Format(dbResult, wsResult, cacheResult));
的問題是,因爲當它被執行dbResult仍然是空的最後一行拋出一個錯誤。只要queryDB.EndInvoke被調用,WaitHandle被髮信號並且執行繼續之前,queryDB.EndInvoke的結果被分配給dbResult。這是否有一個整潔/優雅的方式?
注意:我應該補充一點,這會影響dbResult,因爲queryDB是最後一個等待處理信號。
更新:雖然我接受了菲利普的回答這是偉大的,下面安德烈的意見,我要補充一點,這也適用:
var waitHandles = new List<WaitHandle>();
var wsResult = 0;
Func<int> callWebService = CallWebService;
var wsAsyncResult = callWebService.BeginInvoke(null, null);
waitHandles.Add(wsAsyncResult.AsyncWaitHandle);
string dbResult = null;
Func<string> queryDB = QueryDB;
var dbAsyncResult = queryDB.BeginInvoke(null, null);
waitHandles.Add(dbAsyncResult.AsyncWaitHandle);
var cacheResult = "";
Func<string> queryLocalCache = QueryLocalCache;
var cacheAsyncResult = queryLocalCache.BeginInvoke(null, null);
waitHandles.Add(cacheAsyncResult.AsyncWaitHandle);
WaitHandle.WaitAll(waitHandles.ToArray());
var wsResult = callWebService.EndInvoke(wsAsyncResult);
var dbResult = queryDB.EndInvoke(dbAsyncResult);
var cacheResult = queryLocalCache.EndInvoke(cacheAsyncResult);
Console.WriteLine(string.Format(dbResult, wsResult, cacheResult));
沒有答案,但升級到Fx4會使這容易得多。 – 2010-10-14 20:31:48