Partilhar via


Execução lado a lado no .NET Framework

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.

A execução lado a lado é a capacidade de executar várias versões de um aplicativo ou componente no mesmo computador. Você pode ter várias versões do Common Language Runtime e várias versões de aplicativos e componentes que usam uma versão do tempo de execução, no mesmo computador ao mesmo tempo.

A ilustração a seguir mostra vários aplicativos usando duas versões diferentes do tempo de execução no mesmo computador. Os aplicativos A, B e C usam o tempo de execução versão 1.0, enquanto o aplicativo D usa o tempo de execução versão 1.1.

Execução lado a lado de diferentes versões de tempo de execução,

O .NET Framework consiste no Common Language Runtime e uma coleção de assemblies que contêm os tipos de API. O tempo de execução e os assemblies do .NET Framework são versionados separadamente. Por exemplo, a versão 4.0 do tempo de execução é, na verdade, a versão 4.0.319, enquanto a versão 1.0 dos assemblies do .NET Framework é a versão 1.0.3300.0.

A ilustração a seguir mostra vários aplicativos usando duas versões diferentes de um componente no mesmo computador. Os aplicativos A e B usam a versão 1.0 do componente, enquanto o aplicativo C usa a versão 2.0 do mesmo componente.

Diagrama que mostra a execução lado a lado de um componente.

A execução lado a lado oferece mais controle sobre quais versões de um componente um aplicativo se vincula e mais controle sobre qual versão do tempo de execução um aplicativo usa.

Benefícios da execução lado a lado

Antes do Windows XP e do .NET Framework, os conflitos de DLL ocorriam porque os aplicativos não conseguiam distinguir entre versões incompatíveis do mesmo código. As informações de tipo contidas em uma DLL foram vinculadas apenas a um nome de arquivo. Um aplicativo não tinha como saber se os tipos contidos em uma DLL eram os mesmos tipos com os quais o aplicativo foi criado. Como resultado, uma nova versão de um componente pode substituir uma versão mais antiga e interromper aplicativos.

A execução lado a lado e o .NET Framework fornecem os seguintes recursos para eliminar conflitos de DLL:

  • Assembléias com nomes fortes.

    A execução lado a lado usa assemblies de nome forte para vincular informações de tipo a uma versão específica de um assembly. Isso impede que um aplicativo ou componente se vincule a uma versão inválida de um assembly. Os assemblies de nome forte também permitem que várias versões de um arquivo existam no mesmo computador e sejam usadas por aplicativos. Para obter mais informações, consulte Assemblies com nome forte.

  • Armazenamento de código com reconhecimento de versão.

    O .NET Framework fornece armazenamento de código com reconhecimento de versão no cache de assembly global. O cache de assembly global é um cache de código em todo o computador presente em todos os computadores com o .NET Framework instalado. Ele armazena assemblies com base em informações de versão, cultura e editor e suporta várias versões de componentes e aplicativos. Para obter mais informações, consulte Global Assembly Cache.

  • Isolamento.

    Usando o .NET Framework, você pode criar aplicativos e componentes que são executados isoladamente. O isolamento é um componente essencial da execução lado a lado. Isso envolve estar ciente dos recursos que você está usando e compartilhar recursos com confiança entre várias versões de um aplicativo ou componente. O isolamento também inclui o armazenamento de arquivos de uma maneira específica da versão. Para obter mais informações sobre isolamento, consulte Diretrizes para criar componentes para execução lado a lado.

Compatibilidade de versões

As versões 1.0 e 1.1 do .NET Framework são projetadas para serem compatíveis entre si. Um aplicativo criado com o .NET Framework versão 1.0 deve ser executado na versão 1.1 e um aplicativo criado com o .NET Framework versão 1.1 deve ser executado na versão 1.0. Observe, no entanto, que os recursos de API adicionados na versão 1.1 do .NET Framework não funcionarão com a versão 1.0 do .NET Framework. Os aplicativos criados com a versão 2.0 serão executados somente na versão 2.0. Os aplicativos da versão 2.0 não serão executados na versão 1.1 ou anterior.

As versões do .NET Framework são tratadas como uma única unidade que consiste no tempo de execução e seus assemblies .NET Framework associados (um conceito conhecido como unificação de assembly). Você pode redirecionar a vinculação de assembly para incluir outras versões dos assemblies do .NET Framework, mas substituir a vinculação de assembly padrão pode ser arriscado e deve ser rigorosamente testado antes da implantação.

Localizando informações de versão do Runtime

As informações sobre com qual versão de tempo de execução um aplicativo ou componente foi compilado e quais versões do tempo de execução o aplicativo requer para ser executado são armazenadas em dois locais. Quando um aplicativo ou componente é compilado, as informações sobre a versão de tempo de execução usada para compilá-lo são armazenadas no executável gerenciado. As informações sobre as versões de tempo de execução que o aplicativo ou componente requer são armazenadas no arquivo de configuração do aplicativo.

Informações de versão do tempo de execução no executável gerenciado

O cabeçalho do arquivo executável portátil (PE) de cada aplicativo gerenciado e componente contém informações sobre a versão de tempo de execução com a qual ele foi criado. O common language runtime usa essas informações para determinar a versão mais provável do tempo de execução que o aplicativo precisa executar.

Informações de versão do tempo de execução no arquivo de configuração do aplicativo

Além das informações no cabeçalho do arquivo PE, um aplicativo pode ser implantado com um arquivo de configuração do aplicativo que fornece informações de versão de tempo de execução. O arquivo de configuração do aplicativo é um arquivo baseado em XML que é criado pelo desenvolvedor do aplicativo e que acompanha um aplicativo. O <elemento requiredRuntime> da seção de <inicialização>, se estiver presente neste arquivo, especifica quais versões do tempo de execução e quais versões de um componente o aplicativo suporta. Você também pode usar esse arquivo em testes para testar a compatibilidade de um aplicativo com diferentes versões do tempo de execução.

O código não gerenciado, incluindo aplicativos COM e COM+, pode ter arquivos de configuração de aplicativo que o tempo de execução usa para interagir com o código gerenciado. O arquivo de configuração do aplicativo afeta qualquer código gerenciado ativado por meio do COM. O arquivo pode especificar quais versões de tempo de execução ele suporta, bem como redirecionamentos de assembly. Por padrão, os aplicativos de interoperabilidade COM que chamam para código gerenciado usam a versão mais recente do tempo de execução instalada no computador.

Para obter mais informações sobre os arquivos de configuração do aplicativo, consulte Configurando aplicativos.

Determinando qual versão do tempo de execução carregar

O common language runtime usa as seguintes informações para determinar qual versão do tempo de execução deve ser carregada para um aplicativo:

  • As versões de tempo de execução que estão disponíveis.

  • As versões de tempo de execução suportadas por um aplicativo.

Versões de tempo de execução suportadas

O tempo de execução usa o arquivo de configuração do aplicativo e o cabeçalho do arquivo executável portátil (PE) para determinar qual versão do tempo de execução um aplicativo suporta. Se nenhum arquivo de configuração do aplicativo estiver presente, o tempo de execução carregará a versão de tempo de execução especificada no cabeçalho do arquivo PE do aplicativo, se essa versão estiver disponível.

Se um arquivo de configuração do aplicativo estiver presente, o tempo de execução determinará a versão de tempo de execução apropriada a ser carregada com base nos resultados do seguinte processo:

  1. O tempo de execução examina o <elemento supportedRuntime> Element no arquivo de configuração do aplicativo. Se uma ou mais das versões de tempo de execução suportadas especificadas no elemento supportedRuntime> estiverem presentes, o tempo de execução carregará a versão de tempo de execução especificada pelo primeiro< elemento supportedRuntime>.< Se esta versão não estiver disponível, o tempo de execução examinará o próximo <elemento supportedRuntime> e tentará carregar a versão de tempo de execução especificada. Se essa versão de tempo de execução não estiver disponível, os elementos supportRuntime> subsequentes <serão examinados. Se nenhuma das versões de tempo de execução suportadas estiver disponível, o tempo de execução falhará ao carregar uma versão de tempo de execução e exibirá uma mensagem para o usuário (consulte a etapa 3).

  2. O tempo de execução lê o cabeçalho do arquivo PE do arquivo executável do aplicativo. Se a versão de tempo de execução especificada pelo cabeçalho do arquivo PE estiver disponível, o tempo de execução carregará essa versão. Se a versão de tempo de execução especificada não estiver disponível, o tempo de execução procurará uma versão de tempo de execução determinada pela Microsoft como compatível com a versão de tempo de execução no cabeçalho PE. Se essa versão não for encontrada, o processo continua para a etapa 3.

  3. O tempo de execução exibe uma mensagem informando que a versão de tempo de execução suportada pelo aplicativo não está disponível. O tempo de execução não está carregado.

    Nota

    Você pode suprimir a exibição dessa mensagem usando o valor NoGuiFromShim na chave do Registro HKLM\Software\Microsoft\. NETFramework ou usando a variável de ambiente COMPLUS_NoGuiFromShim. Por exemplo, você pode suprimir a mensagem para aplicativos que normalmente não interagem com o usuário, como instalações autônomas ou serviços do Windows. Quando essa exibição de mensagem é suprimida, o tempo de execução grava uma mensagem no log de eventos. Defina o valor do Registro NoGuiFromShim como 1 para suprimir essa mensagem para todos os aplicativos em um computador. Como alternativa, defina a variável de ambiente COMPLUS_NoGuiFromShim como 1 para suprimir a mensagem para aplicativos executados em um contexto de usuário específico.

Nota

Depois que uma versão de tempo de execução é carregada, os redirecionamentos de vinculação de assembly podem especificar que uma versão diferente de um assembly individual do .NET Framework seja carregada. Esses redirecionamentos de vinculação afetam apenas o assembly específico que é redirecionado.

Nomes de montagem parcialmente qualificados e execução lado a lado

Como eles são uma fonte potencial de problemas lado a lado, as referências de assembly parcialmente qualificadas podem ser usadas apenas para vincular a assemblies dentro de um diretório de aplicativo. Evite referências de assembly parcialmente qualificadas em seu código.

Para atenuar referências de assembly parcialmente qualificadas no código, você pode usar o <elemento qualifyAssembly> em um arquivo de configuração de aplicativo para qualificar totalmente as referências de assembly parcialmente qualificadas que ocorrem no código. Use o <elemento qualifyAssembly> para especificar apenas campos que não foram definidos na referência parcial. A identidade do assembly listada no atributo fullName deve conter todas as informações necessárias para qualificar totalmente o nome do assembly: nome do assembly, chave pública, cultura e versão.

O exemplo a seguir mostra a entrada do arquivo de configuração do aplicativo para qualificar totalmente um assembly chamado myAssembly.

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<qualifyAssembly partialName="myAssembly"
fullName="myAssembly,
      version=1.0.0.0,
publicKeyToken=...,
      culture=neutral"/>
</assemblyBinding>

Sempre que uma instrução de carga de assembly faz referência myAssembly, essas definições de arquivo de configuração fazem com que o tempo de execução traduza automaticamente a referência parcialmente qualificada myAssembly para uma referência totalmente qualificada. Por exemplo, Assembly.Load("myAssembly") torna-se Assembly.Load("myAssembly, version=1.0.0.0, publicKeyToken=..., culture=neutral").

Nota

Você pode usar o método LoadWithPartialName para ignorar a restrição de common language runtime que proíbe que assemblies parcialmente referenciados sejam carregados do cache de assembly global. Este método deve ser usado apenas em cenários remotos, pois pode facilmente causar problemas na execução lado a lado.

Title Description
Como: Ativar e desativar o redirecionamento automático de vinculação Descreve como vincular um aplicativo a uma versão específica de um assembly.
Configurando o redirecionamento de vinculação de assembly Explica como redirecionar referências de vinculação de assembly para uma versão específica dos assemblies do .NET Framework.
Execução lado a lado em processo Discute como você pode usar a ativação de host de tempo de execução lado a lado em processo para executar várias versões do CLR em um único processo.
Montagens no .NET Fornece uma visão geral conceitual de montagens.
Domínios de Aplicação Fornece uma visão geral conceitual de domínios de aplicativo.

Referência

<Elemento supportedRuntime>