Взаимное исключение

У меня есть приложение, которое использует коллекцию, в данном случае очередь, из разных потоков. Объект ставится в очередь в одном потоке, а другой удаляется из очереди в другом потоке.

Эти действия могут выполняться одновременно, что приведет к возникновению исключения, такого как исключение аргумента вне диапазона, когда счетчик коллекций переопределяется.

Я ищу красивый и правильный, чтобы исключить эти действия одно из другого.

  1. что я имею в виду под хорошим внешним видом, так это то, что я не хочу создавать свою собственную коллекцию, производную от этой, которая включает механизм блокировки (объекта)

  2. Я не хочу использовать идею мозгового штурма, которая у меня была, которая довольно уродлива.

    enqueueOk = false;
    while (!enqueueOk)
    {
           try
           {
               Qsockets.Enqueue(currentSoc);
               enqueueOk = true;
           }
           catch { } 
    }

Я думал, конечно, использовать блокировку или мьютекс, но это будет иметь место только в том случае, если я оберну эти действия в процедуру, которая будет вызываться из каждого потока, и решу либо поставить в очередь, либо удалить из очереди, что также было бы долго и уродливо

edit:
потому что никто не видит мой ответ внизу

Я просто использовал механизм блокировки на самой коллекции

lock(Qsockets)
{
   Qsockets.Enqueue(currentSoc); 
}

person eran otzap    schedule 28.03.2011    source источник


Ответы (7)


Похоже на классический сценарий Производитель-Потребитель. Вы проверили этот хороший пример?

person mcabral    schedule 28.03.2011
comment
Тема по этой ссылке устарела и информации о ней сейчас нет. - person vohrahul; 16.07.2018

Можно ли использовать ТПЛ? ConcurrentQueue автоматически обрабатывает параллельные действия.

http://msdn.microsoft.com/en-us/library/dd267265.aspx

person Ryan Bennett    schedule 28.03.2011
comment
... с помощью замков. Я не думаю, что ОП будет избегать оператора блокировки, явно или неявно. - person KeithS; 29.03.2011
comment
Согласованный. Он не обязательно говорит никаких замков. Он просто хочет красивое решение. Эта проблема была решена. Не нужно изобретать велосипед. - person Ryan Bennett; 29.03.2011

У вас всегда есть класс ConcurrentQueue из .Net 4, если .Net 4 вариант. Что реализует блокировку внутри класса.

person Mikael Svenson    schedule 28.03.2011
comment
извините, .Net 3.5 настолько высок, насколько это возможно, где мне нужно проверить эту вещь. 10x за информацию - person eran otzap; 29.03.2011
comment
Библиотека ReactiveExtensions написана в версии 3.5 и включает эти классы, если я не ошибаюсь. - person Ryan Bennett; 30.03.2011

Вы можете использовать параллельную очередь или Синхронизировать очередь.

person Aliostad    schedule 28.03.2011

Используйте ConcurrentQueue (доступно в версии 4.0). См. http://msdn.microsoft.com/en-us/library/dd267265.aspx

person Richard Schneider    schedule 28.03.2011

Оператор блокировки — это лучший способ справиться с такими вещами, и «поточно-ориентированные» коллекции, встроенные в .NET Framework, полагаются на них. Просто сделай это.

person KeithS    schedule 28.03.2011
comment
я не думаю, что статус блокировки работает в этом случае, я пытался заблокировать один и тот же объект в разных потоках, и это не сработало. - person eran otzap; 29.03.2011

я только что сделал вывод из поста в байтах, что могу просто заблокировать фактическую коллекцию

lock(Qsockets) { Qsockets.Enqueue(currentSoc); }

person eran otzap    schedule 28.03.2011