VB .net队列与线程的奇怪行为

时间:2017-11-19 20:24:34

标签: vb.net multithreading queue thread-safety

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

App结构如下所示:

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);
};

直到解析过程并在commport线程中添加到队列控制台时,确切地写入了buffer_work中的消息的发送和复制是排队的:

1 ID: 100 val:0
2 ID: 200 val:0
3 ID: 201 val:0
4 ID: 100 val:1
5 ID: 200 val:1
6 ID: 201 val:1
...
148 ID: 100 val:49
149 ID: 200 val:49
150 ID: 201 val:49

但问题出现了,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条消息,但看起来队列以奇怪的方式排队......多次添加相同的消息,而不是buffer_work中的确切内容......并且在传输结束时我应该有3x49值100,201和202 ID,但它不是。 我认为fifo队列的行为类似于入队A,B,C和我出队获得C,B,A。好吧,它有效,但是当我将所有消息排入队列之后,我就会出列。

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

If Form1._DataQueue.Count = 150 Then

所以等待在comm线程中排队所有150条已解析的消息,然后控制台打印出在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

所以队列看起来像是一个1元素的队列,但我需要那个队列将是commport线程和UI线程之间的消息缓冲区,所以没有消息会丢失......即使UI线程会被激活一点更长的时间......

感谢您提供帮助,并提示如何解决此问题... 此致!

0 个答案:

没有答案