我已经看到很多关于如何BlockingCollection<T>
在生产者-消费者场景中使用 a 的示例,甚至是如何在此处一次使用一个元素。我对并行编程很陌生,所以我面临以下问题:
实际上,问题在于如何编写ConsumerProducerExample.ConsumerMethod
下面示例中的方法,以便它为数组中的每个元素消耗前 2double
个BlockingCollection<Double>
,然后为数组中的每个元素消耗下一个 2 double
,依此类推。
我已经在下面的示例中编写了该方法,但这不是我希望它工作的方式。这是我在上面链接的示例中所知道的。恰恰相反:就像这里一样,它会double
在跳转到BlockingCollection<Double>
数组的下一个之前消耗掉每个。而且,我希望它只消耗两个double
,然后跳转到下一个BlockingCollection<Double>
,消耗两个double
,等等。完成数组循环后,它应该再次double
为每个BlockingCollection<Double>
元素消耗下两个,依此类推。
public class ConsumerProducerExample
{
public static BlockingCollection<Double>[] data;
public static Int32 nEl = 100;
public static Int32 tTotal = 1000;
public static Int32 peakCounter = 0;
public static void InitData()
{
data = new BlockingCollection<Double>[nEl];
for (int i = 0; i < nEl; i++) data[i] = new BlockingCollection<Double>();
}
public static void ProducerMethod()
{
Int32 t = 0, j;
while (t < ConsumerProducerExample.tTotal)
{
j = 0;
while (j < ConsumerProducerExample.nEl)
{
data[j].Add(Math.Sin((Double)t / 10.0D));
j++;
}
t++;
}
j = 0;
while (j < ConsumerProducerExample.nEl)
{
data[j].CompleteAdding();
j++;
}
}
public static void ConsumerMethod()
{
// THE PROBLEM IS WITH THIS METHOD
Double x1, x2;
Int32 j = 0;
while (j < Program.nEl)
{
while (!data[j].IsCompleted)
{
try
{
x1 = data[j].Take();
x2 = data[j].Take();
}
catch (InvalidOperationException)
{
break;
}
if (x1 * x2 < 0.0)
{
Program.peakCounter++;
}
}
j++;
}
}
}
它们应该像这样使用:
ConsumerProducerExample.InitData();
Task task1 = Task.Factory.StartNew(ConsumerProducerExample.ProducerMethod);
Task task2 = Task.Factory.StartNew(ConsumerProducerExample.ConsumerMethod);
有什么建议么?
简而言之,这是一种尝试同时计算nEl
微分方程解中的峰值(sin(x)
在本例中,解由 表示)。