Ожидание блокировки для выпуска с помощью Thread.Sleep ()?

  

Выполняется следующее: Ожидание блокировки для выпуска с помощью ManualResetEvent и Quartz.

Я написал простой механизм блокировки, который сохраняет состояния блокировок в базе данных. Теперь мне нужно дождаться Lock для выпуска или таймаута через определенное время (блокирование основного потока, это намеренно). Моя реализация выглядит следующим образом:

/// <summary>Waits for the lock to be released within the given timeout.</summary>
/// <param name="lockName">The name of the lock.</param>
/// <param name="timeout">The timeout in seconds.</param>
/// <returns>True if the Lock was released.</returns>
public bool waitForLock(String lockName, Int32 timeout)
{
    // IsLocked(String) does query the database for the status
    while(locker.IsLocked(lockName) && timeout > 0)
    {
        Threading.Thread.Sleep(1000);
        timeout--;
    }

    return !locker.IsLocked(lockName);
}

Я всегда получаю немного зуд, если мне нужно использовать Thread.Sleep, но я не уверен, почему.

Что-то не так с этим дизайном /подходом, и это укусит меня позже? Или есть лучший способ справиться с этим?

Изменить: Дополнительные пояснения: у меня есть полный контроль над locker и все, что связано с ним. Основная цель этого - убедиться, что некоторые операции не будут перекрываться, каждая из этих операций должна занимать менее 5 секунд. Нагрузка на сервер не является проблемой, поскольку реалистичное максимальное количество клиентов, одновременно ожидающих блокировку, может быть 10 (в моем случае).

Блокирование потока не так интенционально, как я уже сказал. Лучше всего было бы, если бы я мог поддерживать перезагрузку сообщений, но я не вижу, как я могу достичь этой цели в сочетании с опросом базы данных (и без необходимости вводить таймер с обратным вызовом).

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

11 голосов | спросил Bobby 27 Maypm11 2011, 12:08:14

3 ответа


11

Более простым ответом может быть использование ManualResetEvent. Вы можете заблокировать текущий поток за период ожидания, пока другой поток не сигнализирует ManualResetEvent.

http://philiprieck.com/blog/archive/2004/01/27 /WaitHandleSample.aspx

http://www.yoda.arachsys.com/csharp/threads/waithandles.shtml

В принципе, блокирование вызовов потоков mre.Wait(), обработка потока работает до тех пор, пока он не вызовет mre.Set(). Нет сна, ничего другого.

Важно, всегда Dispose вашего ManualResetEvent s. Утечка ручек - плохой вызов, этот объект выходит в мир COM.

ответил Travis 27 Maypm11 2011, 16:19:14
4

Функция может блокироваться до одной секунды слишком долго (если блокировка освобождается, сразу после ее входа в режим сна).

ответил Henrik 27 Maypm11 2011, 14:06:43
3
  • 1сек может быть прекрасным, но лучший выбор будет зависеть от его характеристик использования. Я рекомендую попробовать разные значения в тестовой системе при ожидаемой производственной нагрузке.

  • Сон не выполняет стандартную пересылку COM и SendMessage. Если вы не вызываете это в главном потоке GUI, это нормально, иначе приложение может оказаться невосприимчивым.

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

  • Обычно имена методов в C # являются PascalCased, а не cammelCased.

У меня также есть некоторые моменты о объекте locker, но я не уверен, сколько у вас контроля над ним.

  • Использование IsLocked (), по-видимому, подразумевает, что оно пытается получить блокировку, но это имя подразумевает, что оно только проверяет, что у вас уже есть. Может быть, GetLock() или AcquireLock() будет лучше имя.

  • Выпускаются ли блокировки, если они не обновляются периодически? Если приложение, удерживающее блокировку, закрывается, соединение db /прерывается внезапно, будет ли блокировка выпущена своевременно без вмешательства?

ответил Brian Reichle 27 Maypm11 2011, 14:20:27

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132