2014-10-27 45 views
0

你好还有stackoverflow!我只需切入下面的步骤: 我有一个使用TCP的服务器/客户端程序,并且我在用于放入读取数据包的队列中遇到了一些问题。一旦数据包被读取,它就会进入队列,如果程序不忙处理数据包,它将处理它并从队列中取出队列。出列与入队不一样

这里是排队数据的代码:

If ReadIndex = ReadBuffer.Length Then 
       SyncLock ReadQueue 
        ReadQueue.Enqueue(ReadBuffer) 
       End SyncLock 
       File.WriteAllBytes(Application.StartupPath & "\Test\" & I & ".bin", ReadBuffer) 
       I += 1 
       If Not Processing(2) Then 
        Processing(2) = True 
        If Not ThreadPool.QueueUserWorkItem(AddressOf HandleReadQueue) Then HandleReadQueue() 
       End If 
      End If 

注意,我写的所有数据包到每个自己的文件(这是用于调试)。我使用ThreadPool来处理不同线程上的读队列。

这里是处理队列中的方法:

Private Sub HandleReadQueue() 
    Dim Data As Byte() 
    SyncLock ReadQueue 
     Data = ReadQueue.Dequeue() 
    End SyncLock 

    File.WriteAllBytes(Application.StartupPath & "\TestReadQueue\" & Y & ".bin", Data) 
    Y += 1 
    If _Parent IsNot Nothing Then 
     HandleClientReadPacket(_Parent, _Pipename, Data) 
    Else 
     HandleClientReadPacket(Me, Nothing, Data) 
    End If 

End Sub 

的文件TestReadQueue是从测试文件夹中的不同。我不知道为什么。而且我知道所有数据都是收到的,因为入队的数据与客户端发送的数据相同。

在这里,你可以看到它的不同:当我使用线程池 http://gyazo.com/feb4a192e47f262a9f23812ae8bc6cf6

此问题不occure,但后来当我不使用的SyncLock是没有必要的..谁能告诉我有什么不对?

+0

你正在排队的字节数组引用 - 你是否重新使用该字节数组,覆盖其中的数据? – 2014-10-27 17:38:35

+0

我的意思是只有在使用ThreadPool时才会出现此问题。 ReadBuffer确实在入队后被修改,但我认为入队是通过值而不是引用? – 2014-10-27 17:49:45

+0

这是VB.NET吗? – dcastro 2014-10-27 17:50:16

回答

2

ReadBuffer确实在其入队后被修改,但我认为入队是通过值而不是引用?

参考由值排队

数组总是引用类型。所有结束于队列中的是对字节数组的引用。例如(C#)

var queue = new Queue<byte[]>(); 
byte[] buffer = { 1 }; 
queue.Enqueue(buffer); 
buffer[0] = 100; 

var dequeued = queue.Dequeue(); 
Console.WriteLine(dequeued[0]); // 100 

如果你想被排队要独立,你将要覆盖的字节数组的参考,你需要克隆它。在C#中,例如,你可以使用:

queue.Enqueue((byte[]) buffer.Clone()); 

使用哪种铸造查看在VB中最合适的 - 但重要的是,该数组被复制,因此独立于原来的数组,你还在修改中。