ConcurrentQueue<byte[]> 中的所有项目都相同
All items in ConcurrentQueue<byte[]> are identical
我有一个 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
中的数据,结果发现包含的每个字节 [64] 都与最新的 bytesIn
相同。我如何确保我添加到 fifo
的数组是值而不是指针(如果这是正确的术语)?
将数组的 copy 加入队列。您可以为此使用 ToArray
扩展名。
while ((i = stream.Read(bytesIn, 0, bytesIn.Length)) != 0)
{
var received = bytesIn.Take(i).ToArray();
fifo.Enqueue(received);
}
我还使用 Take
到 trim 缓冲区,并仅复制接收到的字节。
或者,正如@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);
}
我认为这里的主要问题是您对在 while
-loop 之外声明的队列添加引用类型的误解。
如果仔细查看您提供的代码,您会发现您只声明了一次 bytesIn
。您将 bytesIn
入队,然后 重写 数组的值。但是,该数组仍然是与以前相同的对象,因此不能再次排队,因此它将数组更改为新值。
那么我们真正想做的是什么?我们想要;
- 阅读流
- 将输出放入 new array-object
- 入队新对象
这正是@dcastro 所做的,但我会为您精简代码;
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.
}
有关更多信息,也许您应该阅读 Reference types。
我有一个 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
中的数据,结果发现包含的每个字节 [64] 都与最新的 bytesIn
相同。我如何确保我添加到 fifo
的数组是值而不是指针(如果这是正确的术语)?
将数组的 copy 加入队列。您可以为此使用 ToArray
扩展名。
while ((i = stream.Read(bytesIn, 0, bytesIn.Length)) != 0)
{
var received = bytesIn.Take(i).ToArray();
fifo.Enqueue(received);
}
我还使用 Take
到 trim 缓冲区,并仅复制接收到的字节。
或者,正如@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);
}
我认为这里的主要问题是您对在 while
-loop 之外声明的队列添加引用类型的误解。
如果仔细查看您提供的代码,您会发现您只声明了一次 bytesIn
。您将 bytesIn
入队,然后 重写 数组的值。但是,该数组仍然是与以前相同的对象,因此不能再次排队,因此它将数组更改为新值。
那么我们真正想做的是什么?我们想要;
- 阅读流
- 将输出放入 new array-object
- 入队新对象
这正是@dcastro 所做的,但我会为您精简代码;
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.
}
有关更多信息,也许您应该阅读 Reference types。