Why is there a queue in C # that scrambles data in its elements?

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;

    // Frequencies of the four Sine curves
    double[] myFrequency = { 1, 2, 5, 10 };

    // Creates the output file.
    StreamWriter sw2 = File.CreateText("c:\\tmp\\QueuedDataTest.txt"); 

    // Main loop to calculate my Sine curves
    while (!worker.CancellationPending)
    {
        // Calculate four Sine curves
        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;
        }

        // Bundle the results and Enqueue them
        sensorData dat = new sensorData();
        dat.data = intDist;
        dat.TimeStamp = time;
        dat.timeIndex = j;

        lock (locker) dataQ.Enqueue(dat);
        wh.Set

        // Output results to file.
        sw2.Write(j.ToString() + ", ");
        foreach (UInt16 dd in dat.intData)
        {
            sw2.Write(dd.ToString() + ", ");
        }
        sw2.WriteLine();

        // Increments time and index.
        j++;
        time += 1 / collectedData.signalFrequency;

        Thread.Sleep(2);
    }
    // Clean up
    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;

            // Dequeue available element if any are there.
            lock (locker)
                if (dataQ.Count > 0)
                {
                    data = dataQ.Dequeue();
                    if (data == null)
                    {
                        sw.Close();
                        return;
                    }
                }

            // Check to see if an element was dequeued. If it was write it to file.
            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();
}

.


+3
2

, UInt16[] intDist ? sensorData? (Btw, sensorData.intData , sensorData.data ?)

:

calculateAndEnqueueData() intDist, sensorData --- , + + ; /.

SUGGESTION:

sensorData , intDist, calculateAndEnqueueData():

    // create new sensorData instance
    sensorData dat = new sensorData();
    dat.TimeStamp = time;
    dat.timeIndex = j;

    // Calculate four Sine curves
    for (int i = 0; i < collectedData.numberOfChannels; i++)
    {
        dat.data[i] = (UInt16) Math.Abs(Math.Sin(2.0 * Math.PI * myFrequency[i] * time);
    }

    // enqueue
    lock (locker) dataQ.Enqueue(dat);
+1

StreamWriter, . .

+9

Source: https://habr.com/ru/post/1702219/


All Articles