Как избавиться от ManualResetEvent - PullRequest
6 голосов
/ 11 марта 2011

Привет Когда я использую следующий код:

 myManualResetEvent.Dispose();

Компилятор выдает эту ошибку:

 'System.Threading.WaitHandle.Dispose(bool)' is inaccessible due to its protection level.

howevr следующая строка работает нормально:

 ((IDisposable)myManualResetEvent).Dispose();

это правильный способ утилизации или во время выполнения может произойти сбой в некоторых сценариях.

Спасибо.

Ответы [ 3 ]

16 голосов
/ 11 марта 2011

Разработчики библиотеки базовых классов .NET решили реализовать метод Dispose, используя явную реализацию интерфейса :

private void IDisposable.Dispose() { ... }

Метод Dispose является закрытым, и единственный способ вызвать его - привести объект к IDisposable, как вы обнаружили.

Причина, по которой это делается, заключается в том, чтобы изменить имя метода Dispose так, чтобы оно лучше описывало расположение объекта. Для ManualResetEvent заказным методом является Close метод.

Для утилизации ManualResetEvent у вас есть два хороших варианта. Использование IDisposable:

using (var myManualResetEvent = new ManualResetEvent(false)) {
  ...
  // IDisposable.Dispose() will be called when exiting the block.
}

или звоните Close:

var myManualResetEvent = new ManualResetEvent(false);
...
// This will dispose the object.
myManualResetEvent.Close();

Подробнее читайте в разделе Настройка имени метода удаления в руководстве по проектированию Реализация финализации и удаления для очистки неуправляемых ресурсов в MSDN:

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

3 голосов
/ 11 марта 2011

WaitHandle.Close

Этот метод является общедоступной версией метода IDisposable.Dispose, реализованного для поддержки интерфейса IDisposable.

2 голосов
/ 11 марта 2011

Согласно документация , WaitHandle.Dispose() и WaitHandle.Close() эквивалентна.Dispose существует, чтобы разрешить закрытие через интерфейс IDisposable.Чтобы вручную закрыть WaitHandle (например, ManualResetEvent), вы можете просто использовать Close напрямую вместо Dispose:

WaitHandle.Close

[...] Этот метод является публичной версией метода IDisposable.Dispose, реализованного для поддержки интерфейса IDisposable.

...