Несколько производителей, несколько потребителей и проблема магазина - PullRequest
0 голосов
/ 17 сентября 2009

У меня есть сценарий, когда несколько производителей работают на разных компьютерах в сети. Это службы Singleton WCF, которые ставят в очередь продукты (выходные данные) в центральном хранилище, которое также является службой Singleton WCF.

Есть потребители, которые забирают продукт из Центрального магазина, позвонив в Центральный магазин по запросу JSON. Продукты поставляются путем разрешения определенных приоритетных ограничений. Производители производят продукцию с очень высокой скоростью, около 10000 в минуту, цель состоит в том, чтобы обслуживать их с той же скоростью для потребителей, а не заставлять их ждать.

Все работает нормально, пока у меня 3-4 производителя и до 10 потребителей. Но когда я увеличиваю Производителей и Потребителей, все замерзает.

Я использовал TimedLock , который является оберткой для Monitor.TryEnter. Я перепробовал все методы синхронизации, такие как ReaderWriterLockSlim и другие публикации в Интернете, но результат тот же. Я избегал ReaderWriterLockSlim, поскольку у меня больше записей, чем операций чтения.

Поскольку я не контролирую потоки Consumer и Producer, которые создаются WCF при доступе к Singleton Store. Мне не удалось внедрить образцы «Производитель / Потребитель», доступные в Интернете. Ниже приведен пример кода хранилища данных.

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 голосов
/ 19 сентября 2009

Вы говорите, что он зависает из-за тупика на _MonitorLock? Используете ли вы потоки ThreadPool, и если да, происходит ли замораживание примерно в то время, когда число потоков достигает предела ThreadPool?

Различались ли вы с разными производителями и потребителями, чтобы увидеть, что ведет к закрытию?

Вы добавили запись в свой код, чтобы увидеть, не зависает ли он, потому что он занимает много времени, чтобы получить следующий объект с наивысшим приоритетом? Если это так, то, возможно, реализация приоритетной очереди поможет (http://www.vcskicks.com/priority-queue.php).

0 голосов
/ 17 сентября 2009

Я не уверен, поможет ли это вообще, но в такой среде я бы исследовал, поможет ли использование рабочего процесса Windows (т. Е. Перераспределение проблем планирования частью платформы). Среда выполнения WF может быть снабжена очередью элементов для работы; и будет выполнять «зеленые» потоки внутри одного рабочего процесса в одном потоке ОС (для большего количества потоков ОС просто добавьте больше рабочих процессов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...