[英]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.Pulse
和Monitor.Wait
是一种乒乓样式的线程控制范例。
您可以在主线程Monitor.Wait()
循环,然后将消息添加到队列中时,可以使用Monitor.Pulse()
释放对等待线程的锁定。
这在语义上更相关,但可能效率较低,因为您的上下文切换是针对每条消息按需进行的。
大约有10种其他方法可以完成此操作,大多数方法在该书中都有概述,但这实质上是其精髓。
有关所有信令方法的示例,请参见约瑟夫书的事件信令部分 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.