prattom
prattom

Reputation: 1743

Is ConcurrentQueue<T> Class really thread safe?

I am receiving data at a fast rate on serial port while at the time in other thread I am processing the packets received on serial port. Thus for thread safe read and write operation I am using concurrentqueue. Following is my code for receiving data on serial port which I am storing in concurrentqueue.

System.Collections.Concurrent.ConcurrentQueue<byte> receivedData = new System.Collections.Concurrent.ConcurrentQueue<byte>();
private void receiveData(object sender, SerialDataReceivedEventArgs e)
{
    while (connectComPort.BytesToRead > 0)
    {
        receivedData.Enqueue((byte)connectComPort.ReadByte());
    }
}

Following is the code for processing data in concurrentqueue which is running in background thread.

private void processBuffer()
{
    while (1 == 1)
    {
        try
        {
            List<byte> storeData = new List<byte>();
            if (startProcessState == 0)
            {

                storeData.Clear();
                break;
            }
            if (receivedData.Count() > 7)
            {
                byte first = 0x00;
                receivedData.TryPeek(out first);
                if (startProcessState == 0)
                {

                    storeData.Clear();
                    break;
                }


                if (first == 0x55)
                {
                    first = 0x00;
                    receivedData.TryDequeue(out first);
                    storeData.Add(first);

                    receivedData.TryPeek(out first);

                    if (first == 0xAA)
                    {
                        receivedData.TryDequeue(out first);
                        storeData.Add(first);

                        if (receivedData.TryDequeue(out first))
                        {
                            storeData.Add(first);
                            receivedData.TryDequeue(out first);
                            storeData.Add(first);

                            receivedData.TryPeek(out first);
                            int sizeBytes = (int)first;
                            int numbTimesLoop = sizeBytes - 4;

                            for (int i = 0; i < numbTimesLoop; i++)
                            {
                                receivedData.TryDequeue(out first);
                                storeData.Add(first);
                            }
                            //File.AppendAllText("hello5.txt", BitConverter.ToString(storeData.ToArray()) + Environment.NewLine);
                            modifiedProcess(storeData); //-- Line 1

                        }
                    }

                    else
                    {
                        receivedData.TryDequeue(out first);
                    }
                }

                else
                {
                    receivedData.TryDequeue(out first);
                }
            }
            else
            {
                Thread.Sleep(30);
            }
        }
        catch (Exception ex)
        {
            Log.Error("huge bug : " + ex.ToString());
        }
    }

The problem is data corruption is happening before calling Line 1 function. Some of the bytes are converted to 0x00(I have checked at the sender end so correct data is being send at other end of serial port.). And before Line 1 if I write data to file then I don't see this bug in the packets written to file. What is the possible reason for this bug? I am assuming that concurrentqueue is not fully thread safe.

Upvotes: 1

Views: 745

Answers (1)

Lucero
Lucero

Reputation: 60190

You should really use the return values returned by TryPeek and TryDequeue. If these return false (e.g. because there is nothing in the queue), you'll end up with a 0x00.

Upvotes: 7

Related Questions