【问题标题】:VB.Net: Retrieving items from a ConcurrentQueue on a threadVB.Net:从线程上的 ConcurrentQueue 中检索项目
【发布时间】:2016-09-09 21:20:22
【问题描述】:

我有一个类在一个线程上运行,它侦听数据并将其推送到字符串的 ConcurrentQueue 中。我正在使用 Enqueue 向其中添加数据,我可以看到队列长度正在增长,因此我知道数据正在正确排队。

在另一个线程上运行的另一个类应该在 FIFO 的基础上取出每条数据。然而,它根本什么都不做。这是应该将数据拉出队列的循环:

Dim data As String = Nothing

While Globals.queueMessages.Count > 0

    queueMessages.TryDequeue(data)
    If (data IsNot Nothing) Then
        Console.WriteLine(data)
    Else
        Console.WriteLine("Failed to dequeue")
    End If
End While

除了使用 Count() 检查队列中的项目数外,我还尝试过 IsEmpty。结果一样!?

虽然似乎有很多关于在 C# 中使用 ConcurrentQueue 的文章,但我没有找到任何 VB.Net 示例,所以我有点卡住了。

帮助!

更新:在 Do ... 循环中包装我的 While ... End While 确实有效,但是当什么都没有发生时会占用线程,因此可能不推荐。有没有更优雅的方法来做到这一点?

【问题讨论】:

    标签: vb.net multithreading concurrent-queue


    【解决方案1】:

    正如您所发现的,您需要连续循环,因为队列允许为空并且您不希望循环退出。只需睡一小段时间以使其重新充满。一个简单的布尔标志来控制你的操作何时完成,这就是终止所需要的。

        Dim data As String = Nothing
    
        While mCancel = False
    
            If queueMessages.TryDequeue(data) Then
                Console.WriteLine(data)
            Else
                Console.WriteLine("Empty")
                Thread.sleep(50)
            End If
    
        End While
    

    【讨论】:

    • 关于使用布尔标志的好技巧,我没有想到这一点。没有为我的线程提供 sleep() 属性。我正在使用 Dim threadParser As Task = Nothing 创建它,然后使用 threadParser = Task.Factory.StartNew(Sub() Parser.Process()) 启动线程会更好吗?
    • 一般规则是不要在线程池线程上休眠。如果它是一个短暂的事情,那就去吧。如果您的线程会在应用程序的生命周期内一直存在,那么添加一个专用线程。导入system.threading访问thread.sleep
    • 只要 Windows 应用程序存在,线程就会一直存在 - 理想情况下,这将是几天甚至几周,因此我已将其转换为线程并且它运行良好。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多