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);