我是关于任务,并行和调度等的新手。在这里我创建了两个blockingcollection。一个用于收集输入,另一个用于输出。我添加了100个项目。所以我认为它们的总数应该是100或0.或者它们的总和等于100。
但是我发现他们都是0.请帮助我用简单的语言理解这些概念。
static void Main(string[] args)
{
new Program().run();
}
void run()
{
int threadCount = 4;
Task[] workers = new Task[threadCount];
Task.Factory.StartNew(consumer);
// We can do other work in parallel
for (int i = 0; i < threadCount; ++i)
{
int workerId = i;
Task task = new Task(() => worker(workerId));
workers[i] = task;
task.Start();
}
for (int i = 0; i < 100; ++i)
{
Console.WriteLine("Queueing work item {0}", i);
inputQueue.Add(i);
Thread.Sleep(50);
}
Console.WriteLine("Stopping adding.");
inputQueue.CompleteAdding();
Console.WriteLine("The count in InputQueue= {0}", inputQueue.Count);// 0
Task.WaitAll(workers);
outputQueue.CompleteAdding();
Console.WriteLine("The count in OutputQueue= {0}", outputQueue.Count); // 0
Console.WriteLine("Done.");
Console.ReadLine();
}
void worker(int workerId)
{
Console.WriteLine("Worker {0} is starting.", workerId);
foreach (var workItem in inputQueue.GetConsumingEnumerable())
{
Console.WriteLine("Worker {0} is processing item {1}", workerId, workItem);
Thread.Sleep(100); // Simulate work.
outputQueue.Add(workItem); // Output completed item.
}
Console.WriteLine("Worker {0} is stopping.", workerId);
}
void consumer()
{
Console.WriteLine("Consumer is starting.");
foreach (var workItem in outputQueue.GetConsumingEnumerable())
{
Console.WriteLine("Consumer is using item {0}", workItem);
Thread.Sleep(25);
}
Console.WriteLine("Consumer is finished.");
}
BlockingCollection<int> inputQueue = new BlockingCollection<int>();
BlockingCollection<int> outputQueue = new BlockingCollection<int>();
}
答案 0 :(得分:3)
你有一个3阶段管道
run -- (inputQueue) -- worker -- (outputQueue) -- consumer
所有3个阶段同时运行,只要1个项目位于inputQueue
,就可以立即取出并移至outputQueue
,只要将一个项目放入outputQueue
1}}它可以立即取出并处理。
所以要计算100,你需要做
(100 - number of items "run" has put in to "inputQueue") + "inputQueue.Count" + some number between 0 and "threadCount" representing items that have been taken out of "inputQueue" but have not yet been put in "outputQueue" + "outputQueue.Count" + the number of items "consumer" has taken out of "outputQueue"
由于您的线程和等待数量完全平衡,因此负载很可能是上面的公式0 + 0 + 4 + 0 + 96
,其中最后4个元素等待在worker
处理,其他所有已经处理过的按consumer
。如果你做了一半的工作线程并使消费者花了4倍的时间来处理你就会有像0 + 48 + 2 + 25 + 25
这样的数字,其中48个等待由工人处理,2个由工人处理,25个等待消费者处理,25已经由消费者处理。