Megosztás:


Szálak megsemmisítése

A szál végrehajtásának leállításához általában a kooperatív lemondási modellt kell használnia. Néha azonban nem lehet egy szálat együttműködő módon leállítani, mert olyan külső kódot futtat, amelyet nem kooperatív lemondásra terveztek. .NET-keretrendszer alkalmazásokban a Thread.Abort metódussal kényszerítve állíthat le egy felügyelt szálat. Híváskor Aborta Common Language Runtime bedob egy ThreadAbortException elemet a célszálba, amelyet a célszál képes elkapni. (A .NET-keretrendszer futtatókörnyezet azonban mindig automatikusan újra beszedi a kivételt a catch blokk után.) További információ: Thread.Abort.

A Thread.Abort metódus nem támogatott a .NET 5 -ben (beleértve a .NET Core-t is) és a későbbi verziókban. Ha a .NET 5+-ban kényszerítve kell leállítja a külső kód végrehajtását, futtassa a külön folyamatban, és használja Process.Kill.

Feljegyzés

  • Amikor az aktuális száltól eltérő szál megszakítására hívja meg a hívást Thread.Abort , nem tudja, hogy milyen kódot hajtottak végre, vagy nem sikerült végrehajtani a ThreadAbortException dobáskor. Nem lehet biztos abban sem, hogy az alkalmazás állapota, illetve az alkalmazás és a felhasználó állapota felelős-e a megőrzéséért. A hívás Thread.Abort például megakadályozhatja a statikus konstruktorok végrehajtását, illetve a felügyelt vagy nem felügyelt erőforrások kiadását.
  • Ha egy szál nem felügyelt kódot hajt végre a metódus meghívásakorAbort, a futtatókörnyezet megjelöli.ThreadState.AbortRequested A kivétel akkor fordul elő, ha a szál visszatér a felügyelt kódhoz.

Miután megszakított egy szálat, nem indítható újra.

A Abort metódus nem okozza azonnal a szál megszakítását, mert a célszál képes elfogni és ThreadAbortException tetszőleges mennyiségű kódot végrehajtani egy finally blokkban. Hívhat Thread.Join , ha várnia kell, amíg a szál véget nem ér. Thread.Join egy blokkoló hívás, amely addig nem tér vissza, amíg a szál ténylegesen le nem áll a végrehajtásról, vagy el nem telik egy opcionális időtúllépési időköz. A megszakított szál meghívhatja a ResetAbort metódust, vagy kötetlen feldolgozást végezhet egy finally blokkban, így ha nem ad meg időtúllépést, a várakozás nem garantált.

A metódus hívására Thread.Join várakozó szálakat más hívásláncok Thread.Interruptis megszakíthatják.

ThreadAbortException kezelése

Ha arra számít, hogy a szál megszakad, akár a saját kódból való hívás Abort , akár egy olyan alkalmazástartomány kiürítése miatt, amelyben a szál fut (AppDomain.Unload a szálak leállítására szolgál Thread.Abort ), a szálnak kezelnie kell a ThreadAbortException szálat, és végre kell hajtania a végleges feldolgozást egy finally záradékban, ahogyan az az alábbi kódban is látható.

Try  
    ' Code that is executing when the thread is aborted.  
Catch ex As ThreadAbortException  
    ' Clean-up code can go here.  
    ' If there is no Finally clause, ThreadAbortException is  
    ' re-thrown by the system at the end of the Catch clause.
Finally  
    ' Clean-up code can go here.  
End Try  
' Do not put clean-up code here, because the exception
' is rethrown at the end of the Finally clause.  
try
{  
    // Code that is executing when the thread is aborted.  
}
catch (ThreadAbortException ex)
{  
    // Clean-up code can go here.  
    // If there is no Finally clause, ThreadAbortException is  
    // re-thrown by the system at the end of the Catch clause.
}  
// Do not put clean-up code here, because the exception
// is rethrown at the end of the Finally clause.  

A törlési kódnak a catch záradékban vagy a finally záradékban kell lennie, mert ThreadAbortException a rendszer a záradék végénfinally, vagy ha nincs finally záradék, a catch záradék végén újra meg kell újítania egy kódot.

A metódus meghívásával megakadályozhatja, hogy a rendszer újra megszedje a kivételt Thread.ResetAbort . Ezt azonban csak akkor kell megtennie, ha a saját kódja okozta a ThreadAbortException.

Lásd még