2009-03-18 19 views
20

Jeśli używam EventWaitHandle (lub AutoResetEvent, ManualResetEvent) do synchronizacji między wątkami, czy muszę wywoływać metody Close() lub Dispose() na tym uchwycie zdarzenia, gdy skończę z nim?Czy muszę usunąć() lub zamknąć() EventWaitHandle?

EventWaitHandle dziedziczy po WaitHandle, która implementuje IDisposable. A FxCop narzeka, jeśli nie zaimplementuję IDisposable na żadnej klasie zawierającej EventWaitHandle. Sugeruje to, że muszę to nazwać.

Jednak żaden z tych przykładów użytkowania MSDN zadzwonić Dispose() lub 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

Jest to tylko przykład Microsoft ignorując własne rady?

Odpowiedz

20

Zasób jednorazowego użytku z EventWaitHandle jest w rzeczywistości SafeHandle (zawinięty w SafeWaitHandle). SafeHandle implementuje finalizator, który ostatecznie upewnia się, że wymagany zasób jest zwolniony, więc powinno być bezpiecznie pozwolić wątkowi odśmiecania/finalizatora obsłużyć go w tym przypadku.

Jednak zawsze dobrze jest jednoznacznie zadzwonić pod numer Dispose(), gdy zasób nie jest już potrzebny.

gwintowania rozdział w C# 3.0 in a Nutshell stanach

Praktyka ta jest (prawdopodobnie) do przyjęcia z czekania uchwyty ponieważ mają lekki ciężar OS (Asynchronous delegaci polegać na dokładnie tego mechanizmu do uwolnienia ich IAsyncResult ' s wait uchwyt).

+0

Twierdzę, że pozwolenie GC na zbieranie jest całkiem niepożądane. Pozostawienie pracy w wątku Finalizer to tylko zła praktyka. Jest tylko jeden wątek finalizatora i sprawiający, że robi więcej, niż powinien, nie jest dobry. Jeśli wątek zostanie zablokowany, Twoja aplikacja zostanie zawieszona. Jeśli wyjątek zostanie zgłoszony w wątku finalizatora, Twoja AppDomain ulega awarii. Posiadanie odpowiedniego wzorca pozbywania się gwarantuje, że GC.SuppressFinalize() jest wywoływana, co tłumi finalizację tego obiektu. Mam przykład implementacji IDisposable - http://dave-black.blogspot.com/2011/03/how-do-you-properly-implement.html –

+0

Zgadzam się i dlatego oświadczam, że powinieneś jawnie nazwać "Dispose" '. –

6

Musisz je jawnie wyrzucić. Funkcja Close() jest dla nich bardziej odpowiednia, ponieważ wywołuje funkcję Dispose().

2

definicje klasy z MSDN:

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

Więc tak musi pan jak WaitHandle jest IDisposable. FxCop uzna to za naruszenie przepisów, jeśli tego nie zrobisz.

+0

Dzięki Peter, ale dlaczego przykłady użycia MSDN nie nazywają Close() ani Dispose()? Czy to tylko Microsoft nie przestrzega ich własnej porady? – GrahamS

+1

Domyślam się, że 50% nie podąża za własną radą, a 50% stara się zachować przykłady tak zwięźle, jak to możliwe .. z dodatkiem osób piszących przykłady (nie rdzeni programiści SDK), nie wiedząc lepiej. –

Powiązane problemy