C# 在.NET2.0/3.5中,如何将消息从一个线程异步排队(字符串)到另一个线程?

C# 在.NET2.0/3.5中,如何将消息从一个线程异步排队(字符串)到另一个线程?,c#,multithreading,.net-3.5,.net-2.0,queue,C#,Multithreading,.net 3.5,.net 2.0,Queue,我找到了一篇关于我想在上实现什么的文章。但是本文是基于.NET4.0的。而MSDN网站只有非常简单的例子。所以决定把这个贴在这里 也就是说,我想通过从队列中获取字符串来实现线程在dos提示窗口中异步显示字符串。另一个线程也可以异步地在字符串队列中添加其他字符串(字符串最大条目为20,一旦填充最大条目,就不再添加)。基于.NET2.0或3.5,我希望运行此应用程序,直到队列为空。(VS2008) 排队实现看起来很简单,因为.Net提供了它,但我不知道如何用这个队列实现异步部分 谢谢。所以我想说的是

我找到了一篇关于我想在上实现什么的文章。但是本文是基于.NET4.0的。而MSDN网站只有非常简单的例子。所以决定把这个贴在这里

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

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


谢谢。

所以我想说的是,您基本上想要使用
ConcurrentQueue
,但是您被困在.NET 3.5中,无法使用它(因为它不存在)

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

开始之前:阅读

它超越了.NET线程,即使只是略读它,也会帮助您避免出现严重的线程错误

有两件事你基本上需要做,让我们把它分解一下:

安全地访问队列 您可以使用实现消息队列,但是需要安全地处理更改此对象的所有操作

这样做的最简单形式是使用

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

这将防止您在对消息进行排队/出列时遇到多线程问题,这样您的生活就会很好

等待消息 要等待消息,您有多种方法可以解决此问题。我在上面链接的电子书中概述了其中的大部分内容

最简单的是
线程.Sleep
循环

while(appIsRunning)
{
    Thread.Sleep(100);
    lock(myQueue)
    {
        while(myQueue.Count > 0)
        {
           Console.WriteLine(myQueue.Dequeue());
        }
    }
}
注意:这不是最好的方法,只是最简单的例子

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

如果队列是空的,它将返回睡眠状态

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

Monitor.Pulse
Monitor.Wait
是乒乓风格的线程控制范例

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

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

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


请参阅所有信令方法的示例。

您可能会发现这个问题的公认答案很有趣:根据您在完成时收到通知时所做的“Asychrous”没有多大意义,而在非阻塞中所做的“Asychrous”可能不值得这么复杂,所以,即使阿雷的答案并不完全符合你的要求,这可能是正确的选择。
while(appIsRunning)
{
    Thread.Sleep(100);
    lock(myQueue)
    {
        while(myQueue.Count > 0)
        {
           Console.WriteLine(myQueue.Dequeue());
        }
    }
}