Vb.net net线程的队列奇怪行为

Vb.net net线程的队列奇怪行为,vb.net,multithreading,queue,thread-safety,Vb.net,Multithreading,Queue,Thread Safety,我正在编写一个vb.net表单应用程序,用于从commport接收数据,在commport_线程上进行解析,并通过队列将消息发送到UI线程 应用程序结构如下所示: Private _SerialCommunicationThread As Thread Public _DataQueue As Queue = Queue.Synchronized(New Queue()) Dim QueueLock As New Object ... Me._SerialCommunicationThread

我正在编写一个vb.net表单应用程序,用于从commport接收数据,在commport_线程上进行解析,并通过队列将消息发送到UI线程

应用程序结构如下所示:

Private _SerialCommunicationThread As Thread
Public _DataQueue As Queue = Queue.Synchronized(New Queue())
Dim QueueLock As New Object
...
Me._SerialCommunicationThread = New Thread(AddressOf THREAD_SerialCommunication)
Me._SerialCommunicationThread.Priority = ThreadPriority.AboveNormal
Me._SerialCommunicationThread.Start()

Private Sub THREAD_SerialCommunication()
  'comm port new instace, settings, start, etc

  do
  ' copy all commport's existing bytes to rec_buffer
  ' parse data in rec_buffer ( my own protocol, every message has 14bytes, last is CRC sum), copy valid message (14 baytes) to buffer_work
  if (CRC is OK) then
    SyncLock QueueLock 'lock queue for adding message
       Me._DataQueue.Enqueue(buffer_work) ' add message
       'Console.WriteLine(received_messages_counter & " ID: " & buffer_work(4) & " val:" & buffer_work(5)) 
       'buffer_work(4) is message ID byte            
       'buffer_work(5) is value byte           
    End SyncLock
  end if

  loop

End sub

...
'UI main thread
Private Sub Timer1_Tick ' interval=10ms
  while Form1._DataQueue.Count > 0 Then
    SyncLock QueueLock
      buf_can = Form1._DataQueue.Dequeue()
      'Console.WriteLine(received_messages_counter2 & " ID: " & buffer_work(4) & " val:" & buffer_work(5)
    End SyncLock
  end while
end sub
我正在从微控制器向COM端口发送数据:

for(i=0,i<50;++i)
{
send_message(ID_100,i); // send message with ID=100 and data=i
send_message(ID_201,i);
send_message(ID_202,i);
};
但问题来了,UI线程给出:

...
131 ID: 201 val:43
132 ID: 201 val:43
133 ID: 200 val:44
134 ID: 200 val:44
135 ID: 200 val:45
136 ID: 200 val:45
137 ID: 200 val:45
138 ID: 100 val:46
139 ID: 100 val:46
140 ID: 100 val:47
141 ID: 100 val:47
142 ID: 100 val:47
143 ID: 100 val:48
144 ID: 100 val:48
145 ID: 100 val:48
146 ID: 201 val:48
147 ID: 201 val:48
148 ID: 201 val:49
149 ID: 201 val:49
150 ID: 201 val:49
所以我得到了150条消息,但看起来队列是以奇怪的方式排队的…多次添加相同的消息,这与缓冲区工作中的情况不完全相同…在传输结束时,我应该在100201和202 ID处有3x49值,但事实并非如此。 我认为fifo队列的行为类似于排队A、B、C,我从队列中得到C、B、A。好的,它可以工作,但当我将所有消息排队,然后我就从队列中出来

在主UI线程中添加条件时:

If Form1._DataQueue.Count = 150 Then
所以,等待在comm线程中将所有150条解析的消息排队,然后console打印在UI线程中收到的150条相同的消息,这些都是最后发送的消息

...
145 ID: 201 val:49
146 ID: 201 val:49
147 ID: 201 val:49
148 ID: 201 val:49
149 ID: 201 val:49
150 ID: 201 val:49
所以队列看起来像是一个单元素队列,但我需要该队列是commport线程和UI线程之间的消息缓冲区,所以不会丢失任何消息。。。即使UI线程的活动时间稍长

谢谢你的帮助和提示如何解决这个问题。。。
问候

如果您想要一个可以在多个线程上访问的队列,那么使用
ConcurrentQueue(Of T)
。这正是它存在的目的。问题解决了。原因是缓冲区被声明为全局(公共)。我移动了声明以执行…循环,现在一切正常,没有消息丢失。如果您想要一个可以在多个线程上访问的队列,请使用
ConcurrentQueue(Of T)
。这正是它存在的目的。问题解决了。原因是缓冲区被声明为全局(公共)。我移动声明做…循环,现在是好的,没有消息丢失。
...
145 ID: 201 val:49
146 ID: 201 val:49
147 ID: 201 val:49
148 ID: 201 val:49
149 ID: 201 val:49
150 ID: 201 val:49