【问题标题】:Dequeue not the same as what is enqueued出队与入队不同
【发布时间】:2014-10-27 17:36:43
【问题描述】:

你好,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 中的文件与 Test 文件夹中的文件不同。我不知道为什么。而且我知道所有数据都被接收,因为排队的数据与客户端发送的数据相同。

在这里你可以看到它的不同: http://gyazo.com/feb4a192e47f262a9f23812ae8bc6cf6

当我使用 ThreadPool 时不会出现这个问题,但是当我不使用 SyncLock 时就没有必要了.. 谁能告诉我有什么问题?

【问题讨论】:

  • 您正在排队一个字节数组引用 - 然后您是否重用该字节数组,覆盖其中的数据?
  • 我的意思是这个问题只有在使用线程池时才会出现。 ReadBuffer 在入队后确实被修改了,但我认为入队是按值而不是引用??
  • 是的,我忘了说;这是 VB.NET。
  • 如果这就是你的意思,那么编辑你的问题,这样说 - 最好也回答我在评论中提出的问题......
  • 我已经为你添加了标签:)

标签: .net vb.net multithreading queue synclock


【解决方案1】:

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 中最合适的类型转换 - 但重要的是该数组是克隆的,因此独立于您仍在修改的原始数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 2018-02-07
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 2017-03-14
    • 2014-10-29
    相关资源
    最近更新 更多