多个生产者,多个消费者和商店问题

时间:2009-09-17 06:55:57

标签: c# multithreading synchronization producer-consumer

我有一个场景,其中多个生产者在网络中的不同机器上运行。这些是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
}

2 个答案:

答案 0 :(得分:0)

我不确定这是否会有任何帮助,但在这种环境下,我会调查是否使用Windows工作流(即将调度问题交给框架的一部分)会有所帮助。可以为WF运行时提供要处理的项目队列;并且将在单个OS线程上的单个工作流内进行绿色线程活动(对于更多OS线程,只需添加更多工作流)。

答案 1 :(得分:0)

你是说因为_MonitorLock死锁而冻结吗?您是否正在使用ThreadPool线程,如果是这样,是否会在线程数达到ThreadPool限制时发生冻结?

你做过不同的生产者和消费者组合,看看是什么导致了锁定?

您是否已将日志记录添加到代码中以查看其是否冻结,因为它需要很长时间才能获取下一个最高优先级的对象?如果是这种情况,那么实现优先级排队可能会有所帮助(http://www.vcskicks.com/priority-queue.php)。