2012-09-19 73 views
0

我在寫一個WPF應用程序,需要根據列表中的項目對WCF服務進行多次調用。異步WCF調用循環使用任務

foreach(var item in items) 
{ 
    var dataAboutItem = MethodThatCallsWCFService(item); 

    // Do work to update UI 
    . 
    . 
    . 
} 

有一個聰明的辦法做到這一點使用任務/ Parallel.ForEach或TPL一些構造,將讓我在後臺線程中的所有服務調用,然後更新UI相應的結果進來每次打電話?

+0

你可以使用C#5.0嗎? – svick

+0

我現在不是現在,但沒有什麼能阻止我。這本質上是我正在寫的一次性使用應用程序。 – John

回答

1

如果你可以使用C#5.0,然後async - await可以幫助您與此有關。 WCF服務的代碼生成器支持async - await,因此它可以生成您的方法的異步版本,這很有用。

你會做的是以異步方式啓動所有請求,並將它們返回的Task存儲在一個集合中。然後,在完成後處理Task。 .NET不支持開箱即用,但可以使用Stephen Toub's Interleaved() method

var tasks = new List<Task<DataAboutItem>>(); 

foreach (var item in items) 
{ 
    // don't await here yet 
    Task<DataAboutItem> dataAboutItemTask = MethodThatCallsWCFServiceAsync(item); 

    tasks.Add(dataAboutItemTask); 
} 

foreach (var bucket in Interleaved(tasks)) 
{ 
    var dataAboutItemTask = await bucket; 
    DataAboutItem dataAboutItem = await dataAboutItemTask; 

    // Do work to update UI 
} 

如果你想掐死調用WCF服務(例如,只能使一次10個請求),你可以代替使用TPL Dataflow,指定MaxDegreeOfParallelism

+0

我想我明白在第二個等待中發生了什麼,但第一個呢?請原諒我的無能。 – John

+0

這主要是「Task」工作順序的人爲因素。當你開始迭代集合時,它必須立即給你一個'Task',但它不知道哪一個會先完成。所以'Interleaved()'的返回類型實際上是'Task > []',這就是爲什麼你需要兩個'awaits'。這一切都在我鏈接到的文章中解釋。 – svick

+0

很酷。我將採取這種方法。我很感激幫助。 – John