Este artigo foi traduzido por máquina.

Tudo sobre o CLR

Tratamento corrompido exceções de estado

Andrew Pardoe

Esta coluna se baseia em uma versão de pré-lançamento do Visual Studio 2010. Todas as informações estão sujeitas a alterações.

Conteúdo

Exatamente o que são exceções?
Exceções de SEH do Win32 e System.Exception
Código e SEH gerenciado
Exceções de estado corrompido
É ainda errado usar catch (Exception e)
Código organizadamente

Você tem o código escrito já que não é bem, mas fique próxima o suficiente? Você teve de escrever código que funciona bem quando tudo correr bem, mas você não estiver muito certo o que acontecerá quando algo der errado? Há uma declaração de simples e incorreta que provavelmente é colocada em um código que você escreveu ou tiveram que manter: catch (Exception e). Parece inocente e simples, mas essa instrução pouco pode causar muitos problemas quando falhar fazer o que você esperava.

Se você já viu código que usa exceções como o código a seguir faz o, você precisa ler esta coluna:

public void FileSave(String name)
{
    try
    {
      FileStream fs = new FileStream(name, FileMode.Create);
    }
    catch (Exception)
    {
      throw new System.IO.IOException("File Open Error!");
    }
}

O erro nesse código é comum: é mais simples de escrever código para capturar todas as exceções que é capturar exatamente as exceções que poderiam ser geradas pelo código sendo executado em seu bloco try. Mas por captura a base da hierarquia de exceção, você acabará swallowing uma exceção de qualquer tipo e convertendo-lo para um IOException.

Manipulação de exceção é um dessas áreas sobre a qual a maioria das pessoas tiver um conhecimento funcional em vez de uma compreensão intimate. Começarei com um pouco de informações de plano de fundo explicando a manipulação de exceção do CLR ponto de vista para aqueles que podem estar mais familiarizados com a manipulação de exceção do programação nativa ou um livro de faculdade antigo. Se você for um profissional antigo sinta-se no tratamento de exceção gerenciado, à vontade para ir em frente para a seção em diferentes tipos de exceções ou o código gerenciado e estruturados de manipulação de exceção (SEH). Certifique-se de leia as seções de alguns últimos, porém.

Exatamente o que são exceções?

Uma exceção é gerado quando uma condição for detectada o sinal que não era esperado na execução normal de um thread de programa. Vários agentes podem detectar condições incorretas e gerar exceções. Código de programa (ou o código da biblioteca usa) pode lançar os tipos derivados de System.Exception, o mecanismo de execução de CLR pode aumentar exceções e código não gerenciado pode elevar exceções bem. Exceções geradas em um thread de execução seguir o segmento através do código nativo e gerenciado, entre AppDomains e, se não tratado pelo programa, são tratadas como exceções não tratadas pelo sistema operacional.

Uma exceção indica que algo incorreto ocorreu. Enquanto cada exceção gerenciada tem um tipo (como System.ArgumentException ou System.ArithmeticException), o tipo só é significativo no contexto no qual a exceção é gerada. Um programa pode manipular uma exceção se ele compreende as condições que causou a exceção ocorra. Mas se o programa não manipular a exceção, ele pode indicar qualquer número de coisas ruins. E depois que a exceção tenha saído do programa, só tem um significado muito geral: inválido algo aconteceu.

Quando o Windows verifica se um programa não manipular uma exceção, ele tenta proteger o programa é dados persistentes (arquivos em disco, configurações do Registro e assim por diante) por encerrar o processo. Mesmo se a exceção originalmente indicado algum estado da benigno, inesperado programa (como falhando ao pop de uma pilha vazia) parece ser um problema sério ao Windows vê-lo porque o sistema operacional não possui o contexto para interpretar corretamente a exceção. Um único segmento em um AppDomain pode derrubar uma instância CLR inteira, não Manipulando uma exceção (consulte a Figura 1 ).

fig01.gif

Figura 1 um thread unhandled causa da exceção o processo inteiro para encerrar

Se exceções são tão perigosas, por que são eles tão popular? Como motorcycles e serras cadeia, o poder bruto das exceções torna muito útil. Fluxo de dados normal em um segmento do programa vai da função através de chamadas e retorna. Cada chamada para uma função cria um quadro de execução na pilha; cada retorno destrói esse quadro. Além da alteração de estado global, o único fluxo de dados em um programa é feito pelo passando dados entre quadros contíguos como parâmetros da função ou valores de retorno. Na ausência de manipulação de exceção, cada chamador precisa verificar o sucesso da função que ele chamado (ou apenas assuma tudo o que sempre seja OK).

A maioria das APIs do Win32 retornam um valor diferente de zero para indicar falha porque Windows não usa o tratamento de exceção. O programador deve quebrar a cada chamada de função com código que verifica o valor retorno da função chamada. Por exemplo, este código de documentação do MSDN sobre como para listar os arquivos em um diretório explicitamente verifica cada chamada para o sucesso. A chamada para FindNextFile(...) é encapsulada em uma verificação para ver se o retorno é diferente de zero. Se a chamada não for bem-sucedida um separado funcionará chamada — (GetLastError) — fornece detalhes da condição excepcional. Observe que cada chamada deve ser verificada com êxito no próximo quadro como valores de retorno são necessariamente limitados ao escopo da função local:

// FindNextFile requires checking for success of each call 
while (FindNextFile(hFind, &ffd) != 0); 
dwError = GetLastError(); 
if (dwError != ERROR_NO_MORE_FILES) 
{ 
  ErrorHandler(TEXT("FindFirstFile")); 
} 
FindClose(hFind); 
return dwError; 

Uma condição de erro só pode passar da função que contém a condição inesperada ao chamador da função. Exceções têm a capacidade de passar os resultados da execução da função fora do escopo da função atual para cada quadro na pilha de até alcançar o quadro que sabe como lidar com a condição inesperada. Sistema de exceção do CLR (chamado um sistema de exceção de dois passos) fornece a exceção para cada predecessora na pilha de chamadas do segmento, começando com o chamador e continuar até que alguma função diz que ele manipulará a exceção (isso é conhecido como a primeira passagem).

O sistema de exceção, em seguida, irá desenrolar o estado de cada quadro na pilha de chamadas entre onde a exceção é gerada e onde ele será manipulado (conhecido como a passagem de segundo). Como esvazia a pilha, o CLR irá executar o Finalmente cláusulas e cláusulas de falhas em cada quadro como unwound. Em seguida, a cláusula catch no quadro tratamento é executada.

Porque o CLR verifica cada predecessora na pilha de chamadas não há nenhuma necessidade do chamador para que um bloco catch — a exceção pode ser detectada em qualquer lugar na pilha. Em vez de código para verificar imediatamente o resultado de cada chamada de função, um programador pode manipular erros em um local longe de onde a exceção foi gerada. Uso de códigos de erro requer o programador inspecionar e passar um código de erro em cada quadro da pilha até que ele atinja o local em que a condição errada pode ser manipulada. Manipulação de exceção libera o programador de inspecionar a exceção em cada quadro na pilha.

Para saber mais sobre lançando tipos de exceções personalizado, consulte" Tratamento de erros: lançamento tipos de exceção personalizada de um aplicativo de servidor COM + gerenciado".

Exceções de SEH do Win32 e System.Exception

Há um efeito colateral interessante que vem da capacidade de capturar exceções longe de onde a exceção foi gerada. Um segmento do programa poderá receber exceções de programa de qualquer quadro ativo na sua pilha de chamadas sem saber onde a exceção foi gerada. Mas exceções sempre não representam uma condição de erro que o programa detecta: um segmento do programa também pode causar uma exceção fora do programa.

Se a execução de um segmento faz com que um processador para falhas, em seguida, controle será transferido para o kernel do sistema operacional, que apresenta a falha para o segmento como uma exceção SEH. Assim como o catch bloco não sabe onde na pilha do thread que foi levantada uma exceção, ele não precisa saber exatamente em que ponto o kernel do sistema operacional gerou a exceção SEH.

O Windows notifica segmentos de programa sobre exceções de sistema operacional usando o SEH. Os programadores de código gerenciado raramente verá essas como o CLR geralmente impede que os tipos de erros indicados pelo Exceções SEH. Mas se o Windows gera uma exceção SEH, o CLR irá entregá-lo para código gerenciado. Embora Exceções SEH em código gerenciado são raras, o código gerenciado não seguro pode geram um STATUS_­ACCESS_VIOLATION que indica que o programa tentou acessar a memória inválida.

Para obter detalhes sobre SEH, consulte artigo de Matt Pietrek" Um curso de memória nos intensidades do Win32 estruturado manipulação de exceção"em janeiro de 1997 emitir de Microsoft Systems Journal .

Exceções de SEH são uma classe diferente dessas exceções gerados pelo seu programa. Um programa pode disparar uma exceção porque ele tentou exibir um item de uma pilha vazia ou tentou abrir um arquivo que não existe. Todas essas exceções faz sentido no contexto de execução do programa. Exceções SEH consulte um contexto fora do seu programa. Uma violação de acesso (VA), por exemplo, indica uma gravação de tentativa para a memória inválida. Ao contrário de erros de programa, uma exceção SEH indica que a integridade do processo do runtime pode ter sido comprometida. Mas embora Exceções SEH sejam diferente de exceções que derivam de System.Exception, quando o CLR fornece a exceção SEH para um segmento gerenciado pode ser detectada com uma instrução catch (Exception e).

Alguns sistemas tentar separar esses dois tipos de exceções. O compilador Microsoft Visual C++ distingue entre exceções disparadas por uma instrução throw do C++ e Exceções SEH Win32 se você compila seu programa com a opção /EH. Essa separação é útil porque um programa normal não sabe como manipular erros que não aumentar. Se um programa C++ tentar adicionar um elemento a um std::vector, ele deve esperar que a operação pode falhar devido à falta de memória, mas um programa correto usando bibliotecas bem escritas não deve ser esperado para lidar com uma violação de acesso.

Essa separação é útil para programadores. Uma VA é um problema sério: uma gravação inesperada na memória de sistema crítico pode afetar qualquer parte do processo é imprevisível. Mas alguns erros SEH, como um erro de divisão por zero resultantes da entrada do usuário inválido (e não verificado), são menos sérios. Enquanto um programa com uma divisão por zero estiver incorreto, é improvável que isso afetará qualquer parte do sistema. Na verdade, é provável que um programa C++ pode manipular um erro de divisão por zero sem destabilizing o restante do sistema. Portanto, enquanto a essa separação é útil, a necessidade de programadores semântica gerenciada bastante não expressar.

Código e SEH gerenciado

O CLR sempre forneceu Exceções SEH para código gerenciado usando os mesmos mecanismos como exceções geradas pelo próprio programa. Não é um problema desde que o código não tenta manipular condições excepcionais que ele não pode manipular razoavelmente. A maioria dos programas com segurança não pode continuar execução após uma violação de acesso. Infelizmente, manipulação de modelo de exceção do CLR tem sempre estimulados usuários para capturar esses erros graves, permitindo que programas para tratar qualquer exceção na parte superior da hierarquia de System.Exception. Mas isso raramente é a coisa certa para fazer.

Escrever catch (Exception e) é um erro programação comum porque as exceções sem tratamento tem conseqüências sérias. Mas você poderia argumentar que se você não souber quais erros serão gerados por uma função, você deve proteger contra todos os possíveis erros quando o programa chama essa função. Isso parece um curso razoável de ação até que você pensa sobre o que significa continuar a execução quando o processo for possivelmente em um estado corrompido. Às vezes, anulando e tentando novamente é a melhor opção: ninguém gosta de ver uma caixa de diálogo do Watson, mas é melhor reiniciar o programa que para ter seus dados corrompidos.

Programas captura exceções decorrente de contextos não compreender é um problema sério. Mas você não pode resolver o problema usando as especificações de exceções ou outro mecanismo de contrato. E é importante que programas gerenciados seja capaz de receber notificação de Exceções SEH porque o CLR é uma plataforma para vários tipos de aplicativos e os hosts. Alguns hosts, como SQL Server, precisará ter controle total do processo do aplicativo. Código gerenciado que interopera com código nativo, às vezes, deve lidar com Exceções SEH ou de exceções do C++ nativas.

Mas a maioria dos programadores que escrevem catch (Exception e), na verdade, não deseja detectar violações de acesso. Eles preferir que execução de suas paradas de programa quando ocorrer um erro grave em vez de permitir que o programa limp junto em um estado desconhecido. Isso é especialmente verdadeiro para programas que hospedam gerenciado add-ins, como Visual Studio ou Microsoft Office. Se um suplemento causa uma violação de acesso e, em seguida, swallows a exceção, o host pode fazer danos ao seu próprio estado (ou arquivos do usuário) sem perceber nunca que algo deu errado.

Na versão 4 do CLR, a equipe de produto está fazendo exceções que indicam um estado de processo corrompido diferente de todas as exceções. Nós são designando sobre uma dúzia SEH exceções para indicar o estado de processo corrompido. A designação está relacionada ao contexto no qual a exceção é gerada em oposição ao tipo de exceção propriamente dito. Isso significa que uma violação de acesso recebida do Windows será marcada como uma exceção de estado corrompido (CSE), mas um gerados no código do usuário pelo throw escrever que System.AccessViolation­Exception nova não será marcado como um CSE. Se você participou PDC 2008, você recebeu uma Community Technology visualizar do Visual Studio 2010 que inclui as alterações.

É importante observar que a exceção não corromper o processo: a exceção é gerada após corrupção for detectada no estado de processo. Por exemplo, quando uma gravação através de um ponteiro em código não seguro faz referência a memória que não pertence ao programa, uma violação de acesso é gerada. A gravação inválida, na verdade, não ocorre, o sistema operacional marcada propriedade a memória e impediu a ação de local de fazer. A violação de acesso indica que o ponteiro se foi corrompido em um momento anterior na execução do segmento.

Exceções de estado corrompido

Na versão 4 e posterior, o sistema de exceção CLR será não entregar CSEs para código gerenciado a menos que o código expressamente tenha indicado que ele pode manipular exceções de estado de processo corrompido. Isso significa que uma instância de catch (Exception e) em código gerenciado não ter a CSE apresentada para ele. Ao fazer a alteração dentro do sistema de exceção CLR você não precisará alterar a hierarquia de exceção ou alterar semântica de manipulação de exceção qualquer linguagem gerenciada.

Por motivos de compatibilidade, a equipe do CLR fornecidos algumas maneiras de permitem que você executar o código antigo no comportamento antigo:

  • Se você quiser recompilar o código criado no Microsoft .NET Framework 3.5 e executá-lo no .NET Framework 4.0 sem ter que atualizar a fonte, você pode adicionar uma entrada em seu arquivo de configuração do aplicativo: legacyCorruptedState­­ExceptionsPolicy = true.
  • Assemblies compilados com o .NET Framework 3.5 ou uma versão anterior do tempo de execução será capaz de processar estado corrompido exceções (em outras palavras, manter o comportamento antigo) quando funcionando com o .NET Framework 4.0.

Se desejar que seu código para manipular CSEs, você deve indicar sua intenção, marcando a função que contém a cláusula de exceções (catch, finally, ou falha) com um novo atributo: System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions. Se um CSE é aumentado, o CLR realizará sua busca por uma cláusula catch coincidente mas pesquisará somente nas funções marcadas com o atributo HandleProcessCorruptedStateExceptions (veja a Figura 2 ).

A Figura 2 usando HandleProcessCorruptedStateExceptions

// This program runs as part of an automated test system so you need
// to prevent the normal Unhandled Exception behavior (Watson dialog).
// Instead, print out any exceptions and exit with an error code.
[HandledProcessCorruptedStateExceptions]
public static int Main()
{
    try
    {
        // Catch any exceptions leaking out of the program
        CallMainProgramLoop();
    }
    catch (Exception e) // We could be catching anything here
    {
        // The exception we caught could have been a program error
        // or something much more serious. Regardless, we know that
        // something is not right. We'll just output the exception
        // and exit with an error. We won't try to do any work when 
        // the program or process is in an unknown state!
        System.Console.WriteLine(e.Message);
        return 1;
    }
    return 0;
  } 

Se uma cláusula catch adequado for encontrada, o CLR Desenrolar a pilha como normal, mas somente executar Finalmente e falhas de blocos (e em C#, o implícita bloco finally de uma usando instrução) nas funções marcadas com o atributo. O atributo HandleProcessCorruptedStateExceptions é ignorado quando encontrados no código parcialmente confiável ou transparente como um host confiável não deseja um suplemento não confiável para capturar e Ignorar essas exceções sérias.

É ainda errado usar catch (Exception e)

Mesmo que o sistema de exceção CLR marca as exceções piores como CSE, ele ainda não é uma boa idéia escrever catch (Exception e) em seu código. Exceções representam um espectro inteiro de situações inesperadas. O CLR pode detectar as exceções piores — Exceções SEH que indicam um estado de processo possivelmente corrompido. Mas outras condições inesperadas ainda podem ser prejudiciais se eles forem ignorados ou lidados com genericamente.

Na ausência de corrupção de processo, o CLR oferece algumas garantias muito fortes sobre segurança de correção e a memória do programa. Ao executar um programa escrito em segurança código Microsoft Intermediate Language (MSIL) pode ter determinado que todas as instruções no seu programa serão executado corretamente. Mas fazer o que dizem as instruções de programa fazer muitas vezes é diferente de fazer o que deseja que o programador. Um programa que seja completamente correto de acordo com para o CLR pode corromper o estado de persistente, como arquivos de programa gravados em um disco.

Veja como um exemplo simples um programa que gerencia um banco de dados de pontuação de teste para uma escola de alta. O programa usa os princípios de design orientado a objeto para encapsular os dados e gera exceções gerenciadas para indicar eventos inesperados. Um dia a secretária da escola pressiona a tecla ENTER uma muito muitas vezes ao gerar um arquivo de nota. O programa tenta exibir um valor de uma fila vazia e gera um QueueEmptyException que vai não tratada por meio de quadros em que a pilha de chamadas.

Em algum lugar próximo ao topo da pilha é uma função, GenerateGrades(), com uma cláusula try/catch que captura a exceção. Infelizmente, GenerateGrades() não tem nenhuma idéia de que os alunos são armazenados em uma fila e não têm qualquer idéia o que fazer com um QueueEmpty­Exception. Mas o programador que escreveu GenerateGrades() não quer que o programa falha sem salvar os dados que é foi calculados até o momento. Tudo o que é gravado com segurança para o disco e o programa sai.

O problema com este programa é que torna um número de suposições que podem estar incorretas. Qual é a dizer que a entrada ausente na fila dos alunos é no final? Talvez o primeiro aluno registrar entendeu ignorado e o décimo. A exceção somente informa o programador que o programa está incorreto. Realizar nenhuma ação — salvando dados em disco ou "recuperação" e continuando a execução — é errado sem formatação apenas. Nenhuma ação correta é possível sem o conhecimento do contexto no qual a exceção foi gerada.

Se o programa tinha detectada uma exceção específica próximo de onde a exceção foi aumentada, ele pode ter sido tomar a ação apropriada. O programa sabe o que significa um QueueEmptyException na função que tenta dequeue aos alunos. Se a função captura essa exceção por tipo — em vez de captura de uma classe inteira de tipos de exceções — seria em uma posição muito melhor para tentar fazer o estado do programa correto.

Em geral, capturar uma exceção específica é a correta coisa a fazer porque ele fornece o contexto da maioria para o manipulador de exceção. Se seu código potencialmente pode capturar duas exceções, em seguida, ele deve ser capaz de lidar com ambos. Escrever código que diz catch (Exception e) deve ser capaz de lidar com literalmente, qualquer situação excepcional. Essa é uma promessa que é muito difícil manter.

Alguns idiomas tentam evitar que os programadores captura de uma classe ampla de exceções. Por exemplo, C++ possui as especificações de exceção, um mecanismo que permite que um programador especificar quais exceções podem ser disparadas nessa função. Java leva isso um passo adiante com exceções marcados, um requisito imposta compilador que uma determinada classe de exceções seja especificada. Em ambos os idiomas, você listar as exceções que podem fluir insuficiente essa função na declaração da função e os chamadores são necessários para manipular essas exceções. Especificações de exceção são uma boa idéia, mas eles tiveram misto resulta em prática.

Há debate rígida como para se qualquer código gerenciado deve poder manipular CSEs. Essas exceções normalmente indicam um erro de nível de sistemas e só devem ser tratadas pelo código que entende o contexto de nível de sistemas. Embora a maioria das pessoas não precisar a capacidade de lidar CSEs, há algumas situações em que é necessário.

Um cenário é quando você está muito próximo a onde a exceção ocorreu. Por exemplo, considere um programa que chama código nativo que é conhecida por estar buggy. Depurando o código que você aprenderá o que às vezes zeros um ponteiro antes de acessá-lo, que causa uma violação de acesso. Convém usar o atributo de HandleProcessCorruptedStateExceptions na função que chama o código nativo usando P/Invoke porque você souber a causa a corrupção do ponteiro e confortáveis que a integridade do processo é mantida.

O outro cenário que pode chamar para o uso desse atributo é quando você estiver quanto você pode ser do erro. Na verdade, você está quase pronto para sair do seu processo. Digamos que você escreveu um host ou uma estrutura que deseja executar alguns log personalizado no caso de um erro. Você pode quebrar sua função principal com um bloco Try/Catch/Finally e marcá-lo com HandleProcessCorruptedStateExceptions. Se um erro inesperadamente fizê-lo todo backup função principal do seu programa, você gravar alguns dados em seu log, fazendo como pouco trabalho quando você precisa e sair o processo. Quando a integridade do processo é em questão qualquer trabalho pode ser perigoso, mas se o log personalizado falhar, às vezes, é aceitável.

Dê uma olhada no diagrama mostrado na Figura 3 . Função aqui 1 (fn1()) for atribuído com [HandleProcess­CorruptedStateExceptions] para sua cláusula catch captura a violação de acesso. O Finalmente bloco na função 3 não será executado mesmo que a exceção será ser detectada na função 1. Função 4 na parte inferior da pilha gera uma violação de acesso.

fig03.gif

A Figura 3 Exception e violação de acesso

Não há nenhuma garantia de uma nesses cenários que o que você está fazendo é completamente seguro, mas há situações em que apenas encerrar o processo é inaceitável. No entanto, se optar por manipular um CSE há uma carga enorme em você como o programador fazê-lo corretamente. Lembre-se de que o sistema de exceção CLR ainda não enviar um CSE para qualquer função que não está marcada com o novo atributo seja durante a primeira passagem (quando ele procura uma cláusula catch correspondentes) ou a segunda passagem (quando ele esvazia o estado de cada quadro e executa por último e blocos de falhas).

O Finalmente bloco existe para garantir que o código sempre é executado, se ou não há uma exceção. (Falha de blocos executar somente quando ocorre uma exceção, mas têm uma garantia semelhante de sempre sendo executado). Essas construções são usadas para limpar recursos críticos, como liberar identificadores de arquivo ou reverter a representação contextos.

Até mesmo código que é escrito para ser confiável por meio do uso de restrita CER (Regiões não ser executados quando um CSE foi aumentado a menos que esteja em uma função que foram marcada com o atributo HandleProcessCorruptedStateExceptions de execução. É muito difícil escrever código correto que manipula um CSE e continua a executar o processo com segurança.

Olhe atentamente no código na Figura 4 para ver o que pode dar errado. Se esse código não estiver em uma função que possa processar CSEs, e o Finalmente bloco não será executado quando ocorre uma violação de acesso. Tudo bem se o processo termina — o identificador de arquivo aberto será liberado. Mas se alguns códigos captura a violação de acesso e tentar restaurar estado, precisa saber o que ele deve fechar este arquivo bem como restaurar qualquer outro estado externo que este programa foi alterado.

A Figura 4 O Finally Block pode não executado

void ReadFile(int index)
    {
      System.IO.StreamReader file = 
        new System.IO.StreamReader(filepath);
          try
          {
            file.ReadBlock(buffer, index, buffer.Length);
          }
          catch (System.IO.IOException e)
          {
            Console.WriteLine("File Read Error!");
          }
          finally
          {
            if (file != null)
                {
                    file.Close()
                }
          }
    }

Se você decidir que você vai lidar com um CSE, seu código precisa esperar que há uma tonelada de estado crítico que não tenha sido unwound. Por fim e blocos de falhas não tiverem sido executados. Regiões de execução restrita não foram executadas. O programa — e o processo — estão em um estado desconhecido.

Se você souber que seu código irá fazer a coisa certa, você saberá o que fazer. Mas se você não estiver certo do estado de seu programa está sendo executado no, é melhor para apenas permitir que o processo de sair. Ou, se o seu aplicativo estiver hospedado, chame a diretiva de escalonamento que seu host tiver especificado. Consulte Alessandro Catorcini e do Brian Grunkemeyer Coluna CLR de dezembro de 2007 Para obter mais informações como escrever código confiável e as CERs.

Código organizadamente

Mesmo que o CLR impede que você captura naively CSEs, ele ainda não é uma boa idéia para capturar excessivamente grande de classes de exceções. Mas catch (Exception e) aparece em um lote de código e é improvável que isso será alterado. Por não fornecer as exceções que representam um estado de processo corrompido ao código que naively captura todas as exceções, você impede que esse código fazer um pior situação sérios.

Na próxima vez que gravar ou manter o código que captura uma exceção, pense sobre o que significa a exceção. É o tipo que é detectada correspondência que seu programa (e as bibliotecas que ele usa) documentadas jogar? Você sabe como tratar a exceção, que o programa possa corretamente e com segurança continuar execução?

Manipulação de exceção é uma ferramenta poderosa que deve ser usada com cuidado e thoughtfully. Se você realmente precisar usar esse recurso — se você realmente precisa manipular exceções que podem indicar um processo corrompido, o CLR irá confiar em você e permitem que você fazer isso. Apenas tenha cuidado e fazê-lo corretamente.

Envie suas dúvidas e comentários para clrinout@microsoft.com.

Andrew Pardoe é gerente de programa para CLR da Microsoft. Ele funciona em muitos aspectos do mecanismo de execução para o tempo de execução do Silverlight e área de trabalho. Ele pode ser contatado em Andrew.Pardoe@Microsoft.com.