2011-08-18 22 views
10

Pracuję nad 2 usługami systemu Windows, które mają wspólną bazę danych, którą chcę zablokować (proces krzyżowy) za pomocą systemu Mutex.Czy powinienem zutylizować Mutex?

Teraz zastanawiam się, czy to jest ok, aby po prostu zadzwoń WaitOne() i ReleaseMutex() w try-finally bloku czy mam również wyrzucać mutex (np w using bloku). Jeśli tak, to chyba powinienem zawsze złapać AbandonedMutexException na metodzie WaitOne(), czy też się mylę?

+0

Potrzebujesz wyjątku AbandonedMutexException, aby poinformować, że usługa posiadająca muteks została nieoczekiwanie zakończona. W takim przypadku * masz * do zaprzestania używania bazy danych i oczekiwania na ponowne uruchomienie drugiej usługi.Używanie trzeciego procesu do działania jako arbiter byłoby rozsądne. –

Odpowiedz

12

Mutex jest obiekt jądra systemu Windows (tutaj zawinięte w obiekcie NET).

Jako taki jest to niezarządzany zasób, który powinien zostać usunięty.

Dokładniej, obiekt .NET zawiera UCHWYT na muteksie, który musi zostać jakoś zwolniony/usunięty.

Nie wierzę, że code sample in the Mutex class docs, gdzie obiekt mutex nie jest usuwany. Chociaż Henzi ma dobry punkt komentarza: Obiekt Mutex jest statyczny i zostanie usunięty przez finalizator lub zniszczony przez jądro systemu Windows, gdy proces się zakończy.

Należy również pamiętać, że Close() udostępnia również obiekt.

Oczywiście, nie ma nic złego w utrzymywaniu istniejącego obiektu Mutex w aplikacji, nawet gdy nie jest używany. Są to lekkie zasoby.

+0

Nie ma jeszcze próbki kodu, musisz ją połączyć: http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx –

+1

zrobione. Następnym razem, edytuj moją odpowiedź ;-) –

+0

Ale od czasu tworzenia usług Windows, myślę, że nie powinienem zawracać sobie głowy zbieraniem podczas "runtime" moich usług (co jest zawsze). Utworzenie nowej instancji Mutex o tej samej nazwie za każdym razem po prostu otoczy tę samą niezarządzaną instancję, prawda? A może stworzy nowe niezarządzane zasoby w kółko? Mógłbym zamknąć muteksa, gdy jedna z moich usług została zatrzymana, aby to wyczyścić? – Koen

2

Musisz dysponować zasobami, z których korzysta waithandle.

Z dokumentacji:

Zwalnia wszystkie zasoby wykorzystywane do bieżącej instancji klasy WaitHandle . (Dziedziczony z WaitHandle).

W waithandle wykorzystywane są zasoby niezarządzane, które powinny zostać usunięte po zakończeniu użytkowania.

MSDN Documentation Mutex

6

Zgodnie z this nazwany Mutex jest automatycznie niszczony, gdy kończy się ostatni proces z zatrzymaniem HANDLE tego Mutexa.

W warunkach innych niż zarządzane MSDN mówi

Użyj funkcji CloseHandle aby zamknąć uchwyt. System zamyka uchwyt automatycznie po zakończeniu procesu. Obiekt mutex jest niszczony, gdy jego ostatni uchwyt został zamknięty.

W .NET należy zadzwonić .Close() na Mutex - to zwolni HANDLE ... ponieważ każdy proces dostaje własną HANDLE przy dostępie nawet o tej samej nazwie Mutex to powszechną praktyką ... niestawienie Close() won” • Pozostaw wszelkie problemy behing po zakończeniu procesu (finalizatory i wszystkie) ...