I am completely puzzled by how my turn works. I am trying (and cannot) write a small multi-threaded application for collecting and displaying data in C #.
After reading the Albahari book and using the Consumer / Producer image that he describes, I got most of the work, except that my data seems to be scrambled into a queue. Before queuing, the fields in my object have the following meanings
timeStamp = 6
data [] = {4936, 9845, 24125, 44861}
After deleting the data, the data looks like
timeStamp = 6
data [] = {64791, 19466, 47772, 65405}
I don’t understand why the values in the submitted data change after dequeue? I am puzzled, so I thought I would drop him there to find out if someone could point me in the right direction, to fix it or point me in the other direction.
Corresponding code
Custom data storage object
Relevant objects and fields. The sensorData class is a separate class for storing my calculations.
public class sensorData
{
public const int bufSize = 4;
public UInt16[] data = new UInt16[4];
public double TimeStamp = 0;
public int timeIndex = 0;
}
The following fields are used to configure the queue and signals between the queue and queue flows.
EventWaitHandle wh = new AutoResetEvent(false);
Queue<sensorData> dataQ = new Queue<sensorData>();
object locker = new object();
Enqueue / Thread Method
This is my workflow that computes four Sine curves and queues the result for processing. I also write the results to a file so that I know what it computed.
private void calculateAndEnqueueData(BackgroundWorker worker, DoWorkEventArgs e)
{
int j = 0;
double time = 0;
double dist;
UInt16[] intDist = new UInt16[sensorData.bufSize];
UInt16 uint16Dist;
double[] myFrequency = { 1, 2, 5, 10 };
StreamWriter sw2 = File.CreateText("c:\\tmp\\QueuedDataTest.txt");
while (!worker.CancellationPending)
{
for (int i = 0; i < collectedData.numberOfChannels; i++)
{
dist = Math.Abs(Math.Sin(2.0 * Math.PI * myFrequency[i] * time);
uint16Dist = (UInt16)dist;
intDist[i] = uint16Dist;
}
sensorData dat = new sensorData();
dat.data = intDist;
dat.TimeStamp = time;
dat.timeIndex = j;
lock (locker) dataQ.Enqueue(dat);
wh.Set
sw2.Write(j.ToString() + ", ");
foreach (UInt16 dd in dat.intData)
{
sw2.Write(dd.ToString() + ", ");
}
sw2.WriteLine();
j++;
time += 1 / collectedData.signalFrequency;
Thread.Sleep(2);
}
sw2.Close();
lock (locker) dataQ.Enqueue(null);
wh.Set();
sw2.Close();
}
Sample line in the output file QueuedDataTest.txt
6, 4936, 9845, 24125, 44861,
Dequeue Data Method
. , .
private void dequeueDataMethod()
{
StreamWriter sw = File.CreateText("C:\\tmp\\DequeueDataTest.txt");
while (true)
{
sensorData data = null;
lock (locker)
if (dataQ.Count > 0)
{
data = dataQ.Dequeue();
if (data == null)
{
sw.Close();
return;
}
}
if (data != null)
{
sw.Write(data.timeIndex.ToString() + ", ");
foreach (UInt16 dd in data.data)
sw.Write(dd.ToString() + ", ");
sw.WriteLine();
}
else
{
wh.WaitOne();
}
}
DequeueDataTest.txt
6, 64791, 19466, 47772, 65405,
1:
.
, . , , , .
CalculateAndEnqueueData()
lock (locker) dataQ.Enqueue(dat);
wh.Set
lock(locker)
{
sw2.Write(j.ToString() + ", ");
foreach (UInt16 dd in dat.intData)
{
sw2.Write(dd.ToString() + ", ");
}
sw2.WriteLine();
}
dequeueDataMethod() ,
lock(locker)
if (dataQ.Count > 0)
{
data = dataQ.Dequeue();
if (data == null)
{
sw.Close();
return;
}
}
locks locker if. -,
lock (locker)
{
sw.Write(data.timeIndex.ToString() + ", ");
foreach (UInt16 dd in data.intData)
sw.Write(dd.ToString() + ", ");
sw.WriteLine();
if (icnt > 10)
{
sw.Close();
return;
}
this.label1.Text = dataQ.Count.ToString();
}
.