Dela via


asynchronousThreadAbort MDA

Kommentar

Den här artikeln är specifik för .NET Framework. Det gäller inte för nyare implementeringar av .NET, inklusive .NET 6 och senare versioner.

Den asynchronousThreadAbort hanterade felsökningsassistenten (MDA) aktiveras när en tråd försöker introducera en asynkron abort i en annan tråd. Synkrona tråd aborter aktiverar asynchronousThreadAbort inte MDA.

Symtom

Ett program kraschar med en ohanterad ThreadAbortException när huvudprogramtråden avbryts. Om programmet skulle fortsätta att köras kan konsekvenserna bli värre än att programmet kraschar, vilket kan leda till ytterligare skadade data.

Åtgärder som är avsedda att vara atomiska har sannolikt avbrutits efter delvis slutförande, vilket lämnar programdata i ett oförutsägbart tillstånd. A ThreadAbortException kan genereras från till synes slumpmässiga punkter i körningen av kod, ofta på platser där ett undantag inte förväntas uppstå. Koden kanske inte kan hantera ett sådant undantag, vilket resulterar i ett skadat tillstånd.

Symtomen kan variera kraftigt på grund av den slumpmässighet som är inneboende i problemet.

Orsak

Kod i en tråd som kallas Thread.Abort metoden på en måltråd för att introducera en asynkron tråd som avbryts. Trådens abort är asynkron eftersom koden som gör anropet till Abort körs på en annan tråd än målet för abortåtgärden. Synkrona tråd aborter bör inte orsaka något problem eftersom tråden Abort som utför bör ha gjort det endast vid en säker kontrollpunkt där programtillståndet är konsekvent.

Asynkrona tråd aborter utgör ett problem eftersom de bearbetas vid oförutsägbara punkter i måltrådens körning. För att undvika detta måste kod som skrivs för att köras på en tråd som kan avbrytas på det här sättet hantera en ThreadAbortException på nästan varje kodrad och se till att programdata hamnar i ett konsekvent tillstånd igen. Det är inte realistiskt att förvänta sig att kod skrivs med det här problemet i åtanke eller att skriva kod som skyddar mot alla möjliga omständigheter.

Anrop till ohanterad kod och finally block avbryts inte asynkront utan omedelbart vid avslut från någon av dessa kategorier.

Orsaken kan vara svår att avgöra på grund av problemets slumpmässighet.

Åtgärd

Undvik koddesign som kräver att asynkrona tråd avbryts. Det finns flera metoder som är lämpligare för avbrott i en måltråd som inte kräver ett anrop till Abort. Det säkraste är att införa en mekanism, till exempel en gemensam egenskap, som signalerar måltråden att begära ett avbrott. Måltråden kontrollerar signalen vid vissa säkra kontrollpunkter. Om den märker att ett avbrott har begärts kan det stängas av på ett korrekt sätt.

Effekt på körningen

Denna MDA har ingen effekt på CLR. Den rapporterar endast data om asynkrona tråd aborter.

Output

MDA rapporterar ID:t för tråden som utför avbrottet och ID:t för tråden som är målet för avbrottet. Dessa kommer aldrig att vara desamma eftersom detta är begränsat till asynkrona aborter.

Konfiguration

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

Exempel

Aktivering av asynchronousThreadAbort MDA kräver bara ett anrop till Abort på en separat tråd som körs. Tänk på konsekvenserna om innehållet i trådstartsfunktionen var en uppsättning mer komplexa åtgärder som kan avbrytas vid valfri godtycklig tidpunkt vid avbrottet.

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();
}

Se även