use*_*136 9 .net c# multithreading task-parallel-library
我在C#/ VS2010中使用Parallel.ForEach循环来进行处理,我有几个问题.
首先我有一个需要从远程web服务中提取信息,然后将需要建立的飞行图像(GDI)的过程.
我有一个类,它将所有功能封装到一个对象中,使用两个主要方法Load()和CreateImage(),并在此对象中包含所有GDI管理/ WebRequests"blackboxed".
然后我创建一个包含所有需要处理的对象的GenericList,并使用以下代码遍历列表:
try
{
Parallel.ForEach(MyLGenericList, ParallelOptions, (MyObject, loopState) =>
{
MyObject.DoLoad();
MyObject.CreateImage();
MyObject.Dispose();
if (loopState.ShouldExitCurrentIteration || loopState.IsExceptional)
loopState.Stop();
});
}
catch (OperationCanceledException ex)
{
// Cancel here
}
catch (Exception ex)
{
throw ex;
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题是:
在此先感谢:)亚当
我不确定并行下载数据是个好主意,因为它会阻塞很多线程。相反,将您的任务拆分为生产者和消费者。然后您可以分别并行化它们中的每一个。
这是单个生产者和多个消费者的示例。
(如果消费者比生产者更快,你可以使用普通的 foreach 而不是 parallel.ForEach)
var sources = BlockingCollection<SourceData>();
var producer = Task.Factory.CreateNew(
() => {
foreach (var item in MyGenericList) {
var data = webservice.FetchData(item);
sources.Add(data)
}
sources.CompleteAdding();
}
)
Parallel.ForEach(sources.GetConsumingPartitioner(),
data => {
imageCreator.CreateImage(data);
});
Run Code Online (Sandbox Code Playgroud)
( GetConsumingPartitioner 扩展是ParallelExtensionsExtras的一部分)
编辑更完整的示例
var sources = BlockingCollection<SourceData>();
var producerOptions = new ParallelOptions { MaxDegreeOfParallelism = 5 };
var consumerOptions = new ParallelOptions { MaxDegreeOfParallelism = -1 };
var producers = Task.Factory.CreateNew(
() => {
Parallel.ForEach(MyLGenericList, producerOptions,
myObject => {
myObject.DoLoad()
sources.Add(myObject)
});
sources.CompleteAdding();
});
Parallel.ForEach(sources.GetConsumingPartitioner(), consumerOptions,
myObject => {
myObject.CreateImage();
myObject.Dispose();
});
Run Code Online (Sandbox Code Playgroud)
使用此代码,您可以优化并行下载量,同时保持 CPU 忙于图像处理。
归档时间: |
|
查看次数: |
2746 次 |
最近记录: |