我找到了一篇关于我想在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书中的事件信号部分。