2010-11-12 204 views
6

我需要從IIS中託管的wcf服務內部進行多個異步調用(可能相關,我不知道)。這些調用是針對其他服務的,但是我通過向服務URL發送一個字符串來創建它們。同步調用它們是可行的,但我有十幾個調用,並且它們是完全獨立的,所以我想通過異步調用它們來加速它們。等待多個異步POST請求

現在,我意識到我可以簡單地使用多線程 - 這可能是最簡單的解決方案 - 但我想我會嘗試異步。

我的代碼是與此類似:

public delegate void Callback(string response); 

public static void InvokeAsync(string request, string url, Callback callback) 
    where TResponse: class 
{ 
    var web = new WebClient(); 
    web.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); 

    web.UploadStringCompleted += (sender, e) => callback.Invoke(e.Result); 
    web.UploadStringAsync(new Uri(url), request); 
} 

//... 
var lockObj = new object(); 
foreach (var item in list) 
    InvokeAsync(item, url, response => { lock(lockObj) newList.Add(response); }); 

以上應該工作,我相信;然而,我的問題是,我不知道如何等待所有的回覆。如果我使用計數器並等待一個循環,直到它變爲零,則不會有任何CPU處理回調。我相信,同樣使用某種形式的信號量。有沒有一種非阻塞的方式來等待我收回所有的迴應? (改變方法的簽名也需要一個回調只會移動問題的一個層面了,我害怕。)

[編輯]這是一個非常接近的問題 - How to invoke async operation as sync? - 但我需要等待多個異步操作。

回答

3

對此,您使用的是AutoResetEvent

嘗試爲您的最後兩行如下所示:在newList包含儘可能多的項目list

var waitEvent = new AutoResetEvent(false); 

foreach (var item in list) 
    InvokeAsync(item, url, response => { lock(lockObj) newList.Add(response); waitEvent.Set(); }); 

while (newList.Count < list.Count) 
    waitEvent.WaitOne(); 

所有項目應完成。當新項目進來時,您將其添加到newList。然後,您發信號waitEventnewList」發生了「某事」。

在主線程中,您只需等到newList中有足夠的項目,然後等待更改爲newList,即waitEvent通知您。

+0

謝謝!我喜歡這個網站。 – 2010-11-12 16:25:00

+0

不客氣。 – 2010-11-12 16:26:54

0

根據HTTP協議,客戶端只能打開2個連接到服務。

+0

http://blogs.msdn.com/b/wenlong/archive/2009/02/08/why-only-two-concurrent-requests-for-load-testing.aspx與您一致,但表示一種解決方法那;如果我達到這個限制,我打算使用建議的解決方案。 – 2010-11-12 16:06:37

+0

HTTP協議沒有對連接進行總體限制,但確實有2個連接(或代理或網關代碼的客戶數量的2倍)應該是有原因的;它往往傾向於在許多情況下,每臺服務器2臺是同時打開的最有效的號碼。 .NET強制執行此操作,但它是可配置的。 – 2010-11-12 16:36:13