我正在尝试理解C#中的Dataflow,所以我写了一个小提琴here,我很好奇为什么我的动作块没有在我的例子中执行。
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
public class Program
{
public static void Main(string[] args)
{
var numberOfProducers = 1;
var numberOfConsumers = 10;
var allProducers = Enumerable.Range(0, numberOfProducers).Select(x => new BroadcastBlock<double>(d =>
{
return d;
},
new DataflowBlockOptions()
{
BoundedCapacity = 500
}));
var allConsumers = Enumerable.Range(0, numberOfConsumers).Select(x => new ActionBlock<double>(d =>
{
Console.WriteLine(String.Format("Consuming {0} on Thread ID: {1}", d, Thread.CurrentThread.ManagedThreadId));
},
new ExecutionDataflowBlockOptions()
{
BoundedCapacity = 500
}));
foreach (var producer in allProducers)
{
foreach (var consumer in allConsumers)
{
producer.LinkTo(consumer);
}
}
Parallel.For(0, 20, (i) =>
{
foreach (var producer in allProducers)
{
Console.WriteLine(String.Format("Posting {0} on Thread ID: {1}", i, Thread.CurrentThread.ManagedThreadId));
producer.Post(i);
}
}
);
}
}
该程序的输出示例如下
在线程ID上发布0:18
在主题ID上发布10:16
在主题ID上发布1:17
在主题ID上发布11:19
在主题ID上发布2:18
在线程ID上发布4:17
在线程ID上发布5:17
在线程ID上发布6:17
在主题ID上发布3:18
在主题ID上发布12:18
在线程ID上发布7:17
在线程ID上发布16:19
在线程ID上发布8:17
在线程ID上发布17:19
在线程ID上发布9:17
在帖子ID上发布18:19
在主题ID上发布19:19
在主题ID上发布13:18
在主题ID上发布14:18
在主题ID上发布15:18
我希望在显示动作块消耗广告块上发布的数据时会混合多行。
答案 0 :(得分:0)
延迟评估是动作块未被执行的原因。
allProducers
和allConsumers
是惰性评估的,因此每次枚举时都会生成新的生产者和新的消费者。因此,producer.LinkTo(consumer)
中引用的生成器与producer.Post(i)
我在调试器中单步执行代码时意识到了这一点,当暂停在producer.Post(i)
时,它显示当前在范围内的生产者有0个与之关联的目标。
解决方案是将ToList
或ToArray
添加到allProducers
和allConsumers
var allProducers = Enumerable.Range(0, numberOfProducers).Select(x => new BroadcastBlock<double>(d =>
{
return d;
})).ToList();
var allConsumers = Enumerable.Range(0, numberOfConsumers).Select(x => new ActionBlock<double>(d =>
{
Console.WriteLine($"Consuming {d} on Thread ID: {Thread.CurrentThread.ManagedThreadId}"); ;
})).ToList();