I've seen lots of examples of how to consume a BlockingCollection<T>
in the producer-consumer scenario, even how to consume one element at a time here. I'm quite new to parallel programming though, so I'm facing the following problem:
The problem, indeed, is how to write the method ConsumerProducerExample.ConsumerMethod
in the example below, such that it consumes the first 2 double
of the BlockingCollection<Double>
for every element in the array, then proceeds to consume the next 2 double
for every element in the array and so on.
I have written the method in the example below, but it is not the way I want it to work. It is what I know how to do based in the exampled I linked above though. It is exactly the opposite way: as it is here, it will consume every double
before jumping to the next BlockingCollection<Double>
of the array. And, again, I want it to consume only two double
, then jump to the next BlockingCollection<Double>
, consume two double
, etc. After completing the array loop, it shall proceed to consume the next two double
for each BlockingCollection<Double>
element again, and so on.
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++;
}
}
}
They should be used like this:
ConsumerProducerExample.InitData();
Task task1 = Task.Factory.StartNew(ConsumerProducerExample.ProducerMethod);
Task task2 = Task.Factory.StartNew(ConsumerProducerExample.ConsumerMethod);
Any suggestions?
In short, this is a try to count peaks in the solutions of nEl
Differential Equations concurrently (the solutions are represented by sin(x)
in this example).