2009-03-18 3 views
20

Если я использую EventWaitHandle (или AutoResetEvent, ManualResetEvent), чтобы синхронизировать между потоками, тогда мне нужно вызвать методы Close() или Dispose() этого дескриптора события, когда я закончил с ним?Нужно ли мне Dispose() или Close() EventWaitHandle?

EventWaitHandle унаследовал от WaitHandle, который осуществляет IDisposable. И FxCop жалуется, если я не реализую IDisposable для любого класса, который содержит EventWaitHandle. Поэтому это говорит о том, что мне нужно это назвать.

Однако ни один из этих примеров использования MSDN не называйте Dispose() или Close():

http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle(VS.80).aspx http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent(VS.80).aspx http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(VS.80).aspx

Это просто пример Microsoft игнорируя свои собственные советы?

ответ

20

Одноразовый ресурс EventWaitHandle на самом деле является SafeHandle (завернутый в SafeWaitHandle). SafeHandle реализует финализатор, который в конечном итоге гарантирует, что необходимый ресурс будет освобожден, поэтому должно быть безопасно разрешить обработчик мусорного коллектора/финализатора в этом случае.

Тем не менее, всегда полезно называть Dispose(), когда ресурс больше не нужен.

резьбы глава C# 3.0 in a Nutshell состояний

Эта практика (возможно) приемлемый с ожиданием ручки, потому что они имеют легкую нагрузку ОС (асинхронные делегатов полагаются на именно этот механизме освободить их IAsyncResult " s подождать ручка).

+0

Я бы сказал, что дать GC собрать это совершенно нежелательно. Выход из работы в поток Finalizer - это просто плохая практика. Существует только один поток финализатора и заставляет его делать больше, чем это действительно должно быть плохо. Если поток заблокирован, ваше приложение зависает. Если в поток финализатора выбрано исключение, ваш AppDomain выйдет из строя. Наличие правильной схемы размещения гарантирует, что GC.SuppressFinalize() вызывается, таким образом, подавляя завершение этого объекта. У меня есть пример реализации IDisposable - http://dave-black.blogspot.com/2011/03/how-do-you-properly-implement.html –

+0

Я согласен, и именно поэтому я заявляю, что вы должны явно называть 'Dispose '. –

6

Вам необходимо явно их утилизировать. Close() более подходит для них, так как он вызывает Dispose().

2

Определения классов из MSDN:

public class EventWaitHandle : WaitHandle 
public abstract class WaitHandle : MarshalByRefObject, IDisposable 

Так да, вы должны, как WaitHandle является IDisposable. FxCop нашел бы это, как правило, нарушением, если вы этого не сделали.

+0

Спасибо, Питер, но почему примеры использования MSDN не вызывали Close() или Dispose()? Разве это просто Microsoft, не следуя собственным советам? – GrahamS

+1

Я бы предположил, что это 50%, не следуя их собственным советам, а 50% стараются как можно более краткими примерами .. с гарниром людей, которые пишут примеры (а не ядро ​​разработчиков sdk), которые не знают лучше. –

Смежные вопросы