C# 如何将Parallel.ForEach的结果发布到在C中连续读取的队列#
在我的应用程序中,我有三个类,C# 如何将Parallel.ForEach的结果发布到在C中连续读取的队列#,c#,parallel-processing,task-parallel-library,C#,Parallel Processing,Task Parallel Library,在我的应用程序中,我有三个类,提取器,转换器和加载器,它们由第四个类,协调器协调提取器,Transformer和Loader非常简单,请执行以下操作: 提取器 公开名为Results的IEnumerable类型的成员,例如通过读取文本文件。提取应该是同步的 变压器 公开一个名为Transform的成员,该成员接受一个字符串,并通过一些耗时的过程将其转换为另一个字符串(此处使用并行处理) 加载器 公开名为Load的成员,该成员接受字符串并将其加载到某种最终形式(例如,另一个文本文件)。加载应该是同
提取器
,转换器
和加载器
,它们由第四个类,协调器
协调<代码>提取器,Transformer
和Loader
非常简单,请执行以下操作:
提取器
公开名为Results
的IEnumerable
类型的成员,例如通过读取文本文件。提取应该是同步的
变压器
公开一个名为Transform
的成员,该成员接受一个字符串,并通过一些耗时的过程将其转换为另一个字符串(此处使用并行处理)
加载器
公开名为Load
的成员,该成员接受字符串并将其加载到某种最终形式(例如,另一个文本文件)。加载应该是同步的
协调器类协调这三个操作。转换过程应该并行完成,然后将结果推送到一个队列中,该队列由加载程序读取Coordinator
的Run()
方法如下所示:
Extractor extractor = new Extractor();
Transformer transformer = new Transformer();
Loader loader = new Loader();
ConcurrentQueue<string> outputs = new ConcurrentQueue<string>();
Parallel.ForEach(extractor.Results, x => outputs.Enqueue(transformer.Transform(x)));
foreach(string output in outputs)
{
loader.Load(output);
}
但是,在将任何输出添加到队列之前,底部的foreach
循环被命中,因此它只是退出
调用transformer.Transform()
的结果可用时,如何让加载立即发生?请尝试使用。在下面的示例中,(生产者-消费者模式的消费者部分)在调用之前不会完成,因此load
将运行,直到fill
完成
var outputs = new BlockingCollection<string>();
// aka Producer
Action fill = () => {
Parallel.ForEach(extractor.Results, x => outputs.Add(transformer.Transform(x)));
outputs.CompleteAdding();
};
// aka Consumer
Action load = () => {
foreach(var o in outputs.GetConsumingEnumerable())
loader.Load(o);
}
Parallel.Invoke(fill, load);
var outputs=newblockingcollection();
//又名制作人
动作填充=()=>{
Parallel.ForEach(extractor.Results,x=>outputs.Add(transformer.Transform(x));
outputs.CompleteAdding();
};
//又名消费者
操作负载=()=>{
foreach(outputs.getconsumineGenumerable()中的var o)
装载机。装载(o);
}
并行调用(填充、加载);
查看生产者/消费者模式。现在已经很老了,但这里有一个c#简单的例子:这是一大堆对我来说是新的东西。谢谢这正中了众所周知的要害。我爱你(众所周知)。
var outputs = new BlockingCollection<string>();
// aka Producer
Action fill = () => {
Parallel.ForEach(extractor.Results, x => outputs.Add(transformer.Transform(x)));
outputs.CompleteAdding();
};
// aka Consumer
Action load = () => {
foreach(var o in outputs.GetConsumingEnumerable())
loader.Load(o);
}
Parallel.Invoke(fill, load);