我有一个场景,其中多个生产者在网络中的不同机器上运行。这些是Singleton WCF服务,它们将中央存储中的产品(输出)排队,这也是Singleton WCF服务。
有些消费者通过JSON请求呼叫中央商店,从中央商店出发产品。通过解决某些优先级约束来交付产品。生产者以每分钟10000左右的非常高的速度生产产品,目的是以相同的速度为消费者提供服务,而不是让他们等待。
只要我有3-4个制作人和最多10个消费者,一切都很好。但随着我增加生产者和消费者的一切冻结。
我使用的是TimedLock,它是Monitor.TryEnter的包装器。我尝试了所有类型的同步技术,如ReaderWriterLockSlim和Web上的其他帖子,但结果是一样的。我正在避免使用ReaderWriterLockSlim,因为我有大量的写入而不是读取。
由于我无法控制由WCF生成的Consumer和Producer线程,因为他们访问了Singleton Store。我无法实现Web上提供的生产者/消费者样本。以下是数据存储的示例代码。
public class Store:IEnumerable<Product>
{
private List<Product> _Products;
private object _MonitorLock;
public Store()
{
_Products = new List<Product>();
_MonitorLock = new object();
}
public void Add(Product Product)
{
lock (_MonitorLock)
{
_Products.Add(Product);
}
}
public void Remove(Product Product)
{
lock (_MonitorLock)
{
_Products.Remove(Product);
}
}
public int Count
{
get
{
lock (_MonitorLock)
{
return _Products.Count;
}
}
}
public IEnumerator<Product> GetEnumerator()
{
List<Product> ProductsCopy;
lock (_MonitorLock)
{
ProductsCopy = new List<Product>(_Products);
}
foreach (Product oEntry in ProductsCopy)
yield return oEntry;
}
public Product GetHighestPriorityProduct()
{
Product oProduct;
lock (_MonitorLock)
{
//Some Logic to Resolve the Priority
_Products.Remove(oProduct);
}
return oProduct;
}
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
答案 0 :(得分:0)
我不确定这是否会有任何帮助,但在这种环境下,我会调查是否使用Windows工作流(即将调度问题交给框架的一部分)会有所帮助。可以为WF运行时提供要处理的项目队列;并且将在单个OS线程上的单个工作流内进行绿色线程活动(对于更多OS线程,只需添加更多工作流)。
答案 1 :(得分:0)
你是说因为_MonitorLock死锁而冻结吗?您是否正在使用ThreadPool线程,如果是这样,是否会在线程数达到ThreadPool限制时发生冻结?
你做过不同的生产者和消费者组合,看看是什么导致了锁定?
您是否已将日志记录添加到代码中以查看其是否冻结,因为它需要很长时间才能获取下一个最高优先级的对象?如果是这种情况,那么实现优先级排队可能会有所帮助(http://www.vcskicks.com/priority-queue.php)。