我正在编写一个WPF应用程序,需要根据列表中的项目对WCF服务进行大量调用。
foreach(var item in items)
{
var dataAboutItem = MethodThatCallsWCFService(item);
// Do work to update UI
.
.
.
}
使用Tasks / Parallel.ForEach或TPL中的某些构造是否有一种聪明的方法可以让我在后台线程上进行所有服务调用,然后相应地更新UI,因为每次调用都有结果?< / p>
答案 0 :(得分: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数据流,指定MaxDegreeOfParallelism
。
答案 1 :(得分:0)
任务并行库
上一个示例有UI
Potential Pitfalls in Data and Task Parallelism
或直接更新UI绑定的公共属性而不是UI。
如果这不会加载CPU,您可能希望使用MaxDegreeOfParallelism来保持太多线程不会旋转。