asynchronousThreadAbort MDA

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

Objawy

Aplikacja ulega awarii z nieobsługiwanym ThreadAbortException działaniem, gdy główny wątek aplikacji zostanie przerwany. Jeśli aplikacja będzie nadal działać, konsekwencje mogą być gorsze niż awaria aplikacji, co może spowodować dalsze uszkodzenie danych.

Operacje, które miały 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 obsługiwać 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 Thread.Abort o nazwie metoda w wątku docelowym w celu wprowadzenia przerwania wątku asynchronicznego. Przerwanie wątku jest asynchroniczne, ponieważ kod, który sprawia, że wywołanie jest Abort uruchomione w innym wątku niż element docelowy operacji przerwania. Przerywanie wątków synchronicznych nie powinno powodować problemu, ponieważ wątek wykonujący Abort ten element powinien to 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ługiwać ThreadAbortException niemal każdy wiersz kodu, dbając o umieszczenie danych aplikacji z powrotem w spójny stan. 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 kodu niezarządzanego i finally bloki nie zostaną przerwane asynchronicznie, ale natychmiast po wyjściu z jednej z tych kategorii.

Przyczyna może być trudna do ustalenia 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. Najbezpieczniej jest wprowadzenie mechanizmu, takiego jak wspólna właściwość, która sygnalizuje wątkowi docelowemu żądanie przerwania. Wątek docelowy sprawdza sygnał w niektórych bezpiecznych punktach kontrolnych. Jeśli zauważy, że zażądano przerwania, można go bezpiecznie zamknąć.

Wpływ na środowisko uruchomieniowe

To rozwiązanie MDA nie ma wpływu na clR. Raportuje tylko dane o przerwach asynchronicznych wątków.

Dane wyjściowe

Usługa 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 przerwania asynchronicznego.

Konfiguracja

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

Przykład

Aktywowanie asynchronousThreadAbort rozwiązania MDA wymaga tylko wywołania w Abort osobnym wątku uruchomionym. Należy wziąć pod uwagę 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ż