0

我有一个场景,多个生产者在网络中的不同机器上运行。这些是单例 WCF 服务,它们在中央存储中对产品(输出)进行排队,这也是单例 WCF 服务。

有些消费者通过 JSON 请求调用中央存储,将产品从中央存储中取出。通过解决某些优先级约束来交付产品。生产者在一分钟内以非常高的速度生产约 10000 件产品,其目的是以同样的速度为消费者提供服务,而不是让他们等待。

只要我有 3-4 个生产者和最多 10 个消费者,一切都很好。但是当我增加生产者和消费者时,一切都冻结了。

我使用的是TimedLock,它是 Monitor.TryEnter 的包装器。我已经尝试过所有类型的同步技术,例如 ReaderWriterLockSlim 和 Web 上的其他帖子,但结果是一样的。我避免使用 ReaderWriterLockSlim,因为我的写入次数多于读取次数。

因为我无法控制由 WCF 生成的消费者和生产者线程,因为它们可以访问 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
}
4

2 回答 2

0

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

您是否已经改变了生产者和消费者的组合,以了解导致锁定的原因?

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

于 2009-09-18T23:21:56.260 回答
0

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

于 2009-09-17T07:18:26.507 回答