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

spa*_*ark 2 c# queue multithreading .net-3.5 .net-2.0

我找到了关于我想在C#中实现Queue实现的内容的文章.但该文章基于.Net 4.0.和MSDN网站只有非常简单的例子.所以决定在这里发布.

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

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

谢谢.

Are*_*ren 5

所以我收集的是你想要基本上使用ConcurrentQueue但是你被困在.NET 3.5中并且不能使用它(因为它不存在).

这可以追溯到简单的操作锁定.您不希望两个线程同时访问同一个对象.

开始之前:阅读本书关于C#Threading by Joseph Albahari

它遍及.NET线程,甚至只是浏览它将帮助您防止遇到错误的线程错误.

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

安全地访问队列

您可以使用它Generic Queue<T> Class来实现消息队列,但是需要安全地处理更改此对象的所有操作.

最简单的方法是使用Lock语句.

lock(myQueue)
{
   myQueue.Enqueue(message);
}
Run Code Online (Sandbox Code Playgroud)

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

这将阻止您在排队/出列邮件时遇到多线程问题,生活将会很好.

等待消息

要等待消息,您可以通过多种方式解决此问题.其中大多数都在我上面链接的电子书中列出.

最简单的是Thread.Sleep循环

while(appIsRunning)
{
    Thread.Sleep(100);
    lock(myQueue)
    {
        while(myQueue.Count > 0)
        {
           Console.WriteLine(myQueue.Dequeue());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

如果队列是空的,它就会回到睡眠状态.

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

Monitor.Pulse并且Monitor.Wait是乒乓式线程控制范例.

您可以在主线程中拥有循环,Monitor.Wait()当您向队列添加消息时,您可以Monitor.Pulse()释放锁定到等待的线程.

这在语义上更相关,但可能效率较低,因为您的上下文切换是按需为每条消息发生的.

还有大约10种其他方法可以做到这一点,大多数都在那本书中概述,但这基本上是它的主旨.

有关所有信令方法的示例,请参阅Joseph's Book的事件信令部分.