繁体   English   中英

如何在.NET 2.0 / 3.5中将消息从一个线程异步排队(字符串)到另一个线程?

[英]How to asynchronously queue (string) messages from one thread to another in .NET 2.0/3.5?

我找到了有关要在C#中的Queue实现中实现的内容的文章。 但是本文基于.Net 4.0。 而MSDN网站仅具有非常简单的示例。 因此决定在这里发布。

也就是说,我想实现一个线程通过从队列中获取字符串在dos提示窗口中异步显示字符串。 另一个线程也可能异步在字符串队列中添加其他字符串(最大字符串输入为20,一次填充最大条目,不再添加)。 而且我想运行此应用程序,直到基于.Net 2.0或3.5的队列为空。(VS2008)

排队实现看起来很简单,因为.Net提供了它,但是我不知道如何使用此队列实现异步部分。

谢谢。

所以我要收集的是,您实际上想使用ConcurrentQueue但是您陷在.NET 3.5中,无法使用它(因为它不存在)。

回到简单的操作锁定。 您不希望两个线程同时访问同一对象。

开始之前 :阅读Joseph Albahari撰写的有关C#线程的本书

它遍历.NET线程,甚至只是略读它也可以帮助您防止遇到严重的线程错误。

您本质上需要做两件事,所以让我们分解一下:

安全地访问队列

您可以使用Generic Queue<T> Class实现您的消息队列, 但是更改此对象的所有操作都必须安全处理。

最简单的形式是使用Lock语句

lock(myQueue)
{
   myQueue.Enqueue(message);
}

您必须锁定所有操作,因此您需要的三个是.Enqueue(...) .Dequeue().Count因为它们都访问数据。

这将防止您遇到使消息排队/出队的多线程问题,并且生活会很好。

等待消息

要等待消息,您有多种解决方法。 我上面链接的电子书概述了其中的大多数内容。

最简单的是Thread.Sleep循环

while(appIsRunning)
{
    Thread.Sleep(100);
    lock(myQueue)
    {
        while(myQueue.Count > 0)
        {
           Console.WriteLine(myQueue.Dequeue());
        }
    }
}

注意:这不是最好的方法,只是最简单的示例

这样做只是安排此线程从现在起至少100ms再次运行。 (没有保证,它将从现在开始运行100毫秒,而不会在该时间之前运行)。 然后,它锁定队列,因此不会发生任何写操作,它清空队列并将行写入屏幕,然后再次循环。

如果队列为空,它将回到睡眠状态。

另一种解决方案是使用Pulse / Wait

Monitor.PulseMonitor.Wait是一种乒乓样式的线程控制范例。

您可以在主线程Monitor.Wait()循环,然后将消息添加到队列中时,可以使用Monitor.Pulse()释放对等待线程的锁定。

这在语义上更相关,但可能效率较低,因为您的上下文切换是针对每条消息按需进行的。

大约有10种其他方法可以完成此操作,大多数方法在该书中都有概述,但这实质上是其精髓。

有关所有信令方法的示例,请参见约瑟夫书的事件信令部分

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM