Правильно ли реализован мьютекс и как от него избавиться?

Я просматриваю код, и одно из предупреждений анализа кода (fxCop) меня очень смутило. Код реализует несколько мьютексов путем создания переменные в начале класса, примерно так:

private Mutex myMutex = new Mutex();

fxCop выскакивает с сообщением о том, что я должен реализовать IDisposable для класса, поскольку класс Mutex реализует его - это предупреждение CA1001. Однако, глядя на Mutex, у него нет метода удаления.

Оказывается, Mutex использует SafeWaitHandle ( который реализует IDisposable - предполагая, что это то, что улавливает fxCop), но мьютекс на самом деле не удаляет его с помощью стандартного одноразового шаблона. У него есть частный метод, который назначается делегату с помощью RuntimeHelpers.CleanupCode, что, как я понимаю, означает, что он будет запускаться при исключении.

Это вызывает два вопроса:

  1. Правильно ли реализован Mutex? Если в Mutex нет исключения, SafeWaitHandle никогда не будет удален.
  2. Что мне следует вызвать в моей утилите для очистки мьютекса?

person Robert MacLean    schedule 25.09.2009    source источник


Ответы (2)


Mutex явно реализует IDisposable.Dispose через свой базовый класс WaitHandle. Он предоставляет функции Dispose через свой общедоступный метод Close (также унаследованный от WaitHandle), который является допустимой реализацией шаблона удаления, в соответствии с рекомендациями:

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

Некоторые классы в System.IO тоже делают это.

person Joren    schedule 25.09.2009
comment
да, конечно :) В тот момент, когда я увидел, как крутятся шестерни, и это имело смысл. - person Robert MacLean; 25.09.2009

использование функции Close () по-прежнему генерирует CA2000 в VS 2013 Pro Update 2 • Функция Dispose () недоступна из-за ее уровня защиты.

Итак, это ошибка или это ошибка в анализе кода из VS?

РЕДАКТИРОВАТЬ: решено с использованием этого кода:

Mutex MyApplicationMutex = null;
try
{
  MyApplicationMutex = new Mutex(true, Program.g_ApplicationMutexName);
  if (MyApplicationMutex.WaitOne(0, false))
  {
    ...
  }
}
finally
{
  // Dispose Mutex
  if (MyApplicationMutex != null)
    MyApplicationMutex.Close();
 }
person Nolmë Informatique    schedule 13.08.2014