2

我有一个 NetworkStream 用于从另一个程序获取数据。数据以 Byte[64] 的形式到达,然后我将其入队到 ConcurrentQueue,以便另一个线程可以出列以便稍后进行分析。队列被实例化:

ConcurrentQueue<byte[]> fifo = new ConcurrentQueue<byte[]>();

然后我将所有正在发送的数据排入队列:

Byte[] bytesIn = new Byte[64];
int i;
while ((i = stream.Read(bytesIn, 0, bytesIn.Length)) != 0)
{
    fifo.Enqueue(bytesIn);
}

然后,如果我(在调试期间)查看其中的数据,fifo就会发现其中包含的每个 byte[64] 都与最新的bytesIn. 如何确保我添加的数组fifo是值而不是指针(如果这是正确的术语)?

4

2 回答 2

7

而是将数组的副本排入队列。您可以ToArray为此使用扩展程序。

while ((i = stream.Read(bytesIn, 0, bytesIn.Length)) != 0)
{
    var received = bytesIn.Take(i).ToArray();
    fifo.Enqueue(received);
}

我还用来Take修剪缓冲区,只复制接收到的字节。

或者,正如@hvd 在评论中所建议的那样,使用Array.Copy会更快

while ((i = stream.Read(bytesIn, 0, bytesIn.Length)) != 0)
{
    var received = new byte[i];
    Array.Copy(bytesIn, 0, received, 0, i);

    fifo.Enqueue(received);
}
于 2015-09-11T10:29:04.387 回答
2

I think the main issue here is your misunderstanding of adding a reference type to the queue which you have declared outside your while-loop.

If you take a close look at the code you provided, you can see you only declare bytesIn once. You enqueue the bytesIn, and then rewrite the value of the array. The array is, however, still the same object as before and can thus not be queued again, hence it changes the array to the new value.

So what's it what we actually want to do? We want to;

  • Read the stream
  • Put the output in a new array-object
  • Enqueue the new object

Which is exactly what @dcastro does, but I'll strip down the code for you;

while ((
         i = stream.Read(bytesIn, 0, bytesIn.Length)) != 0    //read the contents of the 
                                                              //stream and put it in 
                                                              //bytesIn, if available 
                                                            )
{
    var received = new byte[i];              //Create a new, empty array, which we are 
                                             //going to put in the queue.

    Array.Copy(bytesIn, 0, received, 0, i);  //Copy the contents of bytesIn into our new
                                             //array. This way we can reuse bytesIn while
                                             //maintaining the received data.

    fifo.Enqueue(received);                  //Enqueue the new array and thus saving it.
} 

For more information, perhaps you should read about Reference types.

于 2015-09-11T10:47:25.843 回答