Xaq*_*ron 4 c# asp.net multithreading
我在ASP.NET中有一个生产者 - 消费者场景.我设计了一个Producer类,一个Consumer类和一个类来保存共享对象并负责Producer和Consumer之间的通信,让我们调用它Mediator.因为我在启动时(在父对象中)分叉执行路径,并且一个线程将调用Producer.Start()并且另一个线程调用Consumer.Start(),我需要传递Mediator对两者Producer和Consumer(via Constructor)的引用.Mediator是一个智能类,它将优化许多内容,如内部队列的长度,但现在将其视为循环阻塞队列.Producer将排入新的对象Mediator,直到队列变满,然后Producer将阻塞.从中Consumer 取出物体Mediator直到队列中没有任何内容.对于线程之间的信令,我在Mediator类中实现了两个方法:Wait()和Pulse().代码是这样的:
Class Mediator
{
private object _locker = new object();
public void Wait()
{
lock(_locker)
Monitor.Wait(_locker);
}
public void Pulse()
{
lock(_locker)
Monitor.Pulse(_locker);
}
}
// This way threads are signaling:
Class Consumer
{
object x;
if (Mediator.TryDequeue(out x))
// Do something
else
Mediator.Wait();
}
Run Code Online (Sandbox Code Playgroud)
在Mediator中我this.Pulse()每次出入队列或出队时都会使用,这样等待线程就会发出信号并继续工作.
但我遇到死锁,因为我从未使用过这种设计信号线程,我不确定设计是否有问题,或者我在其他地方做错了什么?
谢谢
这里没有太多代码可以继续,但我最好的猜测是你有一个锁定问题.如果Mediator.Pulse在此之前调用,Mediator.Wait则即使队列中存在某些内容,信号也会丢失.以下是实现阻塞队列的标准模式.
public class BlockingQueue<T>
{
private Queue<T> m_Queue = new Queue<T>();
public void Enqueue(T item)
{
lock (m_Queue)
{
m_Queue.Enqueue(item);
Monitor.Pulse(m_Queue);
}
}
public T Dequeue()
{
lock (m_Queue)
{
while (m_Queue.Count == 0)
{
Monitor.Wait(m_Queue);
}
return m_Queue.Dequeue();
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意Monitor.Wait,只有在队列为空时才会调用它.还要注意它是如何在while循环中调用的.这是因为a Wait没有优先权,Enter因此Dequeue即使呼叫Wait准备好返回,进入的新线程也可能占用最后一个项目.如果没有循环,线程可能会尝试从空队列中删除项目.
| 归档时间: |
|
| 查看次数: |
3539 次 |
| 最近记录: |