2009-02-11 116 views
1

在我的WPF客戶端中,我有一個循環調用WCF服務來更新某些記錄。當循環完成時,我會顯示一條消息「更新完成」。在循環中異步調用WCF服務

我正在改變我的WCF調用到異步調用現在。

ServiceClient client = new ServiceClient(); 
    client.UpdateRecordsCompleted +=new System.EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_UpdateRecordsCompleted); 

    foreach (MyItem item in someCollection) 
    { 
     client.UpdateRecordsAsync(item); 
    } 

    MessageBox.Show("Update complete"); 

我不需要在每個操作的競爭事件中做任何事情。我只需要在末尾之一顯示一條消息。

任何想法?

編輯:我可能會將此移植到Silverlight,所以這就是爲什麼我需要異步調用該服務。我不認爲我可以使用背景工作者。

+0

只是好奇,爲什麼不使用標準的for循環,當你在你的最後一個項目,設置像isLastItem = true的布爾,並在事件處理程序,檢查isLastItem ,並顯示消息?一旦顯示了消息,您可以將該變量重置爲false,以便隨後的調用工作 – kd7 2009-02-11 17:08:30

+0

即使您只是自己編寫BackgroundWorker,也可以使用BackgroundWorker ... – MichaelGG 2009-02-11 20:42:03

回答

2

我將一個線程安全字段添加到您的WPF窗口來跟蹤客戶的數量更新用戶已排隊:

private int recordsQueued = 0; 

調度各個異步操作之前,recordsQueued設置爲someCollection.Count。

recordsQueued = someCollection.Count; 

最後,在client_UpdateRecordsCompleted中,遞減recordsQueued;如果是零,顯示「更新完成」消息:

private void client_UpdateRecordsCompleted(AsyncCompletedEventArgs args) { 
    if (Interlocked.Decrement(ref recordsQueued) == 0) 
    MessageBox.Show("Update complete.");  
} 
+0

易失性不會在這裏幫助,因爲您有多個線程讀取並遞減。刪除易失性,並使用互鎖減少。 – MichaelGG 2009-02-11 17:28:51

2

如果你不想壓倒請求您的服務器的另一種方法是使用一個後臺工作,做所有的工作在一個正常的循環與同步請求。後臺工作人員已經擁有報告進度和完成的方法,這些方法可以方便地在正確的線程上報告給主應用程序。假設你想用你的GUI來做東西,而不是隻顯示完整的對話框。

2

也許是這樣的:

ServiceClient client = new ServiceClient(); 
var count = someCollection.Count; 
client.UpdateRecordsCompleted += (_,__) => { 
    if (Interlocked.Decrement(ref count) == 0) { 
     MessageBox.Show("Update complete."); 
    } 
} 

foreach (MyItem item in someCollection) 
{ 
    client.UpdateRecordsAsync(item); 
}