如何在.NET2.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());
        }
    }
}

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

这只是简单地安排这个线程从现在起至少100毫秒再次运行。(从现在起,它不会跑100毫秒,只是在那之前不会)。然后它锁定队列,这样就不会发生写入,清空队列并将行写入屏幕,然后再次循环。

如果队列是空的,它就会重新进入睡眠状态。

另一种解决方案是使用脉冲/等待

CCD_ 7和CCD_。

你可以在主线程Monitor.Wait()中有你的循环,当你向队列添加消息时,你可以Monitor.Pulse()来释放锁,它指向一个等待的线程。

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

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

有关所有信号方法的示例,请参阅Joseph书中的事件信号部分。

最新更新