2009-10-12 15 views

Odpowiedz

23

Po pierwsze, żadna z nich nie jest dobrym konstruktem synchronizacji wątków.

Po pierwsze, Thread.Abort mówi: "Nie obchodzi mnie, co robisz, po prostu przestań to robić i pozostaw wszystko w tej chwili". Jest to w zasadzie programowy sposób mówienia "Hej, pokonaj to". Jeśli twój wątek ma otwarte pliki, te pliki pozostaną otwarte, dopóki garbage collection nie przejdzie do finalizacji obiektów.

Thread.Abort powinien być zawsze używany, a nawet wtedy prawdopodobnie nie, w przypadku, gdy domena aplikacji, w której wątek działa wewnątrz, jest zrywane, najlepiej tylko wtedy, gdy proces jest kończony.

Po drugie, Thread.Interrupt to dość dziwna bestia. Zasadniczo mówi: "Nie obchodzi mnie, na co czekasz, przestań na to czekać". Dziwne jest to, że jeśli wątek nie czeka na nic, zamiast tego "nie obchodzi mnie, na co będziesz czekać na następny, ale kiedy to zrobisz, natychmiast przestań na to czekać".

Oba te znaki wskazują na to, że narzucasz swoją wolę na wątku, który nie został zaprojektowany do mówienia takich rzeczy.

Aby poprawnie przerwać wątek, wątek powinien okresowo sprawdzać flagę, czy jest to prosta zmienna zmienna typu Boolean, czy obiekt zdarzenia. Jeśli flaga mówi "Powinieneś teraz zakończyć", wątek powinien się zakończyć, powracając z metod w uporządkowany sposób.

Aby prawidłowo obudzić wątek, w miejscu, w którym musi czekać na obiekty synchronizacji, powinien znajdować się obiekt "proszę przestań czekać", na który również czeka. Tak więc w zasadzie dla obiektu, którego potrzebuje, zostaje zasygnalizowany, lub obiekt "proszę przestań czekać" zostaje zasygnalizowany, określić, który z nich zrobił, i zrobić to, co właściwe.

Więc zamiast Thread.Abort i Thread.Interrupt, należy napisać swoje wątki za pomocą zwykłych przedmiotów synchronizacji, jak wydarzenia, muteksy, semaforów itp

Z tego samego powodu, Thread.Suspend i Thread.Resume powinny być pozostawione w spokoju , a także zostały zastąpione w późniejszych wersjach .NET.

10

ile dzwonisz Abort lub Interrupt na wątku aktualnie wykonującego (jak ASP.NET nie do wypowiedzenia wniosek nagle, na przykład) w zasadzie nie można nazwać je w sposób bezpieczny wątku.

Użyj WaitHandle lub Monitor.Wait/Pulse, aby czekać w trybie czuwania. Powinieneś przerwać tylko inne wątki, jeśli rozbijasz aplikację, w zasadzie - bo inaczej możesz skończyć w nieznanym stanie.

Zobacz przykład jak to zrobić ładnie.

+0

Dobry artykuł Jon.By the Way, gdzie mogę znaleźć Twoją transmisję internetową? – user186973

+0

@threadinglearner: jaki webcast masz na myśli? –

+0

Wszystko o C# – user186973

2

Thread.Abort() podnosi wyjątek ThreadAbortException na docelowym wątku. Zasadniczo ma na celu wymuszenie zakończenia wątku. Nie jest zalecaną praktyką zatrzymywania przetwarzania wątku.

Thread.Interrupt() przerywa wątek będący w stanie WaitSleepJoin - zasadniczo blokuje zasób, taki jak WaitHandle. Pozwala to dzwoniącemu odblokować wątek.

Żadne z nich nie jest tak naprawdę "bezpieczne dla wątków" - w tym sensie, że mają one w zamierzeniu wpływać na zachowanie nici w sposób trudny do przewidzenia.

Ogólnie zaleca się używanie obiektów synchronizacji (takich jak WaitHandles lub Semafores), aby umożliwić bezpieczną synchronizację wątków.

1

Różnica między Przerwaniem a Przerwaniem polega na tym, że podczas gdy obydwaj rzucają wyjątek (wyjątek ThreadAbortException i ThreadInterruptException), wywołanie Abort spowoduje ponowne wyrzucenie wyjątku na końcu bloku catch i upewni się, że zakończysz bieżący wątek.

Powiązane problemy