c# – 使用线程和EventWaitHandle的生产者/消费者模式
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 使用线程和EventWaitHandle的生产者/消费者模式,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3018字,纯文字阅读大概需要5分钟。
内容图文
![c# – 使用线程和EventWaitHandle的生产者/消费者模式](/upload/InfoBanner/zyjiaocheng/806/a1a2b97a851549e2babd19ac180eac26.jpg)
我想这是一种代码审查,但这是我对生产者/消费者模式的实现.我想知道的是,在某种情况下,ReceivingThread()或SendingThread()方法中的while循环可能会停止执行.请注意EnqueueSend(DataSendEnqeueInfo信息)是从多个不同的线程调用的,我可能不能在这里使用任务,因为我必须在一个单独的线程中使用命令.
private Thread mReceivingThread;
private Thread mSendingThread;
private Queue<DataRecievedEnqeueInfo> mReceivingThreadQueue;
private Queue<DataSendEnqeueInfo> mSendingThreadQueue;
private readonly object mReceivingQueueLock = new object();
private readonly object mSendingQueueLock = new object();
private bool mIsRunning;
EventWaitHandle mRcWaitHandle;
EventWaitHandle mSeWaitHandle;
private void ReceivingThread()
{
while (mIsRunning)
{
mRcWaitHandle.WaitOne();
DataRecievedEnqeueInfo item = null;
while (mReceivingThreadQueue.Count > 0)
{
lock (mReceivingQueueLock)
{
item = mReceivingThreadQueue.Dequeue();
}
ProcessReceivingItem(item);
}
mRcWaitHandle.Reset();
}
}
private void SendingThread()
{
while (mIsRunning)
{
mSeWaitHandle.WaitOne();
while (mSendingThreadQueue.Count > 0)
{
DataSendEnqeueInfo item = null;
lock (mSendingQueueLock)
{
item = mSendingThreadQueue.Dequeue();
}
ProcessSendingItem(item);
}
mSeWaitHandle.Reset();
}
}
internal void EnqueueRecevingData(DataRecievedEnqeueInfo info)
{
lock (mReceivingQueueLock)
{
mReceivingThreadQueue.Enqueue(info);
mRcWaitHandle.Set();
}
}
public void EnqueueSend(DataSendEnqeueInfo info)
{
lock (mSendingQueueLock)
{
mSendingThreadQueue.Enqueue(info);
mSeWaitHandle.Set();
}
}
P.S这里的想法是当队列为空时使用WaitHandles将线程置于休眠状态,并在新项目入队时发出信号以启动它.
UPDATE
对于可能尝试使用TPL或任务实现生产者/消费者模式的人,我将离开这个https://blogs.msdn.microsoft.com/benwilli/2015/09/10/tasks-are-still-not-threads-and-async-is-not-parallel/.
解决方法:
就个人而言,对于简单的生产者 – 消费者问题,我只使用BlockingCollection.不需要手动编写自己的同步逻辑.如果队列中没有项目,则消费线程也将阻塞.
如果您使用此类,以下是您的代码:
private BlockingCollection<DataRecievedEnqeueInfo> mReceivingThreadQueue = new BlockingCollection<DataRecievedEnqeueInfo>();
private BlockingCollection<DataSendEnqeueInfo> mSendingThreadQueue = new BlockingCollection<DataSendEnqeueInfo>();
public void Stop()
{
// No need for mIsRunning. Makes the enumerables in the GetConsumingEnumerable() calls
// below to complete.
mReceivingThreadQueue.CompleteAdding();
mSendingThreadQueue.CompleteAdding();
}
private void ReceivingThread()
{
foreach (DataRecievedEnqeueInfo item in mReceivingThreadQueue.GetConsumingEnumerable())
{
ProcessReceivingItem(item);
}
}
private void SendingThread()
{
foreach (DataSendEnqeueInfo item in mSendingThreadQueue.GetConsumingEnumerable())
{
ProcessSendingItem(item);
}
}
internal void EnqueueRecevingData(DataRecievedEnqeueInfo info)
{
// You can also use TryAdd() if there is a possibility that you
// can add items after you have stopped. Otherwise, this can throw an
// an exception after CompleteAdding() has been called.
mReceivingThreadQueue.Add(info);
}
public void EnqueueSend(DataSendEnqeueInfo info)
{
mSendingThreadQueue.Add(info);
}
内容总结
以上是互联网集市为您收集整理的c# – 使用线程和EventWaitHandle的生产者/消费者模式全部内容,希望文章能够帮你解决c# – 使用线程和EventWaitHandle的生产者/消费者模式所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。