Udostępnij za pośrednictwem


asynchronousThreadAbort MDA

Uwaga

Ten artykuł jest specyficzny dla programu .NET Framework. Nie ma zastosowania do nowszych implementacji platformy .NET, w tym .NET 6 i nowszych wersji.

Asystent asynchronousThreadAbort zarządzanego debugowania (MDA) jest aktywowany, gdy wątek próbuje wprowadzić asynchroniczne przerwanie do innego wątku. Przerywane wątki synchroniczne nie aktywują mdA asynchronousThreadAbort .

Objawy

Aplikacja ulega awarii, ThreadAbortException gdy główny wątek aplikacji zostanie przerwany. Jeśli aplikacja miała być nadal wykonywana, konsekwencje mogą być gorsze niż awaria aplikacji, co może spowodować dalsze uszkodzenie danych.

Operacje, które mają być niepodzielne, prawdopodobnie zostały przerwane po częściowym zakończeniu, pozostawiając dane aplikacji w nieprzewidywalnym stanie. Element ThreadAbortException można wygenerować na podstawie pozornie losowych punktów wykonywania kodu, często w miejscach, w których nie ma powstać wyjątek. Kod może nie być w stanie obsłużyć takiego wyjątku, co powoduje uszkodzenie stanu.

Objawy mogą się znacznie różnić ze względu na losowość związaną z problemem.

Przyczyna

Kod w jednym wątku o nazwie Thread.Abort metoda w wątku docelowym w celu wprowadzenia przerywania wątku asynchronicznego. Przerwanie wątku jest asynchroniczne, ponieważ kod, który wykonuje wywołanie Abort elementu , jest uruchomiony w innym wątku niż cel operacji przerwania. Przerywane synchroniczne wątki nie powinny powodować problemu, ponieważ wątek wykonujący Abort to powinno zrobić tylko w bezpiecznym punkcie kontrolnym, w którym stan aplikacji jest spójny.

Przerywane wątki asynchroniczne stanowią problem, ponieważ są przetwarzane w nieprzewidywalnych punktach wykonywania wątku docelowego. Aby tego uniknąć, kod napisany do uruchomienia w wątku, który może zostać przerwany w ten sposób, będzie musiał obsłużyć ThreadAbortException niemal każdy wiersz kodu, dbając o ponowne umieszczenie danych aplikacji w spójnym stanie. Nie można oczekiwać, że kod zostanie napisany z tym problemem lub napisać kod, który chroni przed wszystkimi możliwymi okolicznościami.

Wywołania niezarządzanego kodu i finally bloków nie zostaną przerwane asynchronicznie, ale natychmiast po wyjściu z jednej z tych kategorii.

Przyczyna może być trudna do określenia ze względu na losowość związaną z problemem.

Rozwiązanie

Unikaj projektowania kodu, który wymaga użycia przerywanych wątków asynchronicznych. Istnieje kilka metod bardziej odpowiednich do przerwania wątku docelowego, które nie wymagają wywołania metody Abort. Najbezpieczniejsze jest wprowadzenie mechanizmu, takiego jak wspólna właściwość, który sygnalizuje wątek docelowy do żądania przerwania. Wątek docelowy sprawdza sygnał w określonych bezpiecznych punktach kontrolnych. Jeśli zauważy, że zażądano przerwania, można go bezpiecznie zamknąć.

Wpływ na środowisko uruchomieniowe

Ta usługa MDA nie ma wpływu na CLR. Raportuje tylko dane o przerwach asynchronicznych wątków.

Wyjście

MdA zgłasza identyfikator wątku wykonującego przerwanie i identyfikator wątku, który jest elementem docelowym przerwania. Nigdy nie będą one takie same, ponieważ jest to ograniczone do asynchronicznych przerwań.

Konfigurowanie

<mdaConfig>
  <assistants>
    <asynchronousThreadAbort />
  </assistants>
</mdaConfig>

Przykład

Aktywowanie rozwiązania asynchronousThreadAbort MDA wymaga tylko wywołania dla Abort oddzielnego uruchomionego wątku. Rozważ konsekwencje, jeśli zawartość funkcji uruchamiania wątku była zestawem bardziej złożonych operacji, które mogą zostać przerwane w dowolnym punkcie przez przerwanie.

using System.Threading;
void FireMda()
{
    Thread t = new Thread(delegate() { Thread.Sleep(1000); });
    t.Start();
    // The following line activates the MDA.
    t.Abort();
    t.Join();
}

Zobacz też