【发布时间】:2017-02-13 05:39:32
【问题描述】:
我想这有点像代码审查,但这是我对生产者/消费者模式的实现。我想知道的是,ReceivingThread() 或 SendingThread() 方法中的 while 循环可能会停止执行。请注意,EnqueueSend(DataSendEnqeueInfo info) 是从多个不同的线程调用的,我可能无法在这里使用任务,因为我必须在单独的线程中使用命令。
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 使线程进入睡眠状态,并在新项目入队时发出信号让它们开始。
更新 我将把这个https://blogs.msdn.microsoft.com/benwilli/2015/09/10/tasks-are-still-not-threads-and-async-is-not-parallel/ 留给那些可能试图使用 TPL 或任务来实现生产者/消费者模式的人。
【问题讨论】:
-
您最好使用BlockingCollection,它会为您处理所有同步逻辑。
-
屏蔽收藏是一个不错的选择,不过你也可以试试TPL Dataflow。如果需要,我可以提供一些示例逻辑。
-
@VMAtm 我一直想了解 TPL 数据流。如果您能给我一些示例逻辑,那将是您的好意,当然,前提是它不会太麻烦。
-
@SushantPoojary 我已经用一些示例添加了答案
-
嗨,Sushant Poojary,请查看this code。
标签: c# multithreading producer-consumer tpl-dataflow blockingcollection