Partilhar via


asynchronousThreadAbort MDA

Nota

Este artigo é específico do .NET Framework. Ele não se aplica a implementações mais recentes do .NET, incluindo o .NET 6 e versões posteriores.

O asynchronousThreadAbort assistente de depuração gerenciado (MDA) é ativado quando um thread tenta introduzir uma interrupção assíncrona em outro thread. Os bloqueios de thread síncrono não ativam o asynchronousThreadAbort MDA.

Sintomas

Um aplicativo falha com um não tratado ThreadAbortException quando o thread do aplicativo principal é abortado. Se o aplicativo continuar a ser executado, as consequências podem ser piores do que a falha do aplicativo, possivelmente resultando em mais corrupção de dados.

As operações destinadas a serem atômicas provavelmente foram interrompidas após a conclusão parcial, deixando os dados do aplicativo em um estado imprevisível. A ThreadAbortException pode ser gerado a partir de pontos aparentemente aleatórios na execução do código, muitas vezes em locais dos quais não se espera que surja uma exceção. O código pode não ser capaz de lidar com tal exceção, resultando em um estado corrompido.

Os sintomas podem variar muito devido à aleatoriedade inerente ao problema.

Motivo

Código em um thread chamado o Thread.Abort método em um thread de destino para introduzir um thread assíncrono abortar. O thread abort é assíncrono porque o código que faz a chamada para Abort está sendo executado em um thread diferente do destino da operação abort. Os bloqueios de thread síncrono não devem causar um problema porque o thread que executa o deve ter feito isso apenas em um ponto de verificação seguro onde o Abort estado do aplicativo é consistente.

Os bloqueios de thread assíncronos apresentam um problema porque são processados em pontos imprevisíveis na execução do thread de destino. Para evitar isso, o código escrito para ser executado em um thread que pode ser abortado dessa maneira precisaria lidar com uma em quase todas as linhas de código, tomando cuidado para colocar os ThreadAbortException dados do aplicativo de volta em um estado consistente. Não é realista esperar que o código seja escrito com esse problema em mente ou escrever um código que proteja contra todas as circunstâncias possíveis.

As chamadas para códigos e finally blocos não gerenciados não serão abortadas de forma assíncrona, mas imediatamente após a saída de uma dessas categorias.

A causa pode ser difícil de determinar devido à aleatoriedade inerente ao problema.

Resolução

Evite o design de código que requer o uso de interrupções de thread assíncronas. Há várias abordagens mais apropriadas para a interrupção de um thread de destino que não exigem uma chamada para Abort. O mais seguro é introduzir um mecanismo, como uma propriedade comum, que sinalize o thread de destino para solicitar uma interrupção. O thread de destino verifica o sinal em determinados pontos de verificação seguros. Se ele notar que uma interrupção foi solicitada, ele pode desligar normalmente.

Efeito no tempo de execução

Este MDA não tem efeito sobre o CLR. Ele só relata dados sobre interrupções de thread assíncronas.

Saída

O MDA relata a ID do thread que executa o abort e o ID do thread que é o destino do abort. Estes nunca mais serão os mesmos porque isso é limitado a abortamentos assíncronos.

Configuração

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

Exemplo

A ativação do asynchronousThreadAbort MDA requer apenas uma chamada para Abort em um thread de execução separado. Considere as consequências se o conteúdo da função de início do thread fosse um conjunto de operações mais complexas que poderiam ser interrompidas em qualquer ponto arbitrário pelo abortamento.

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

Consulte também