Criando cópias de sombra de assemblies

Observação

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

A criação de cópias de sombra permite que os assemblies usados em um domínio de aplicativo sejam atualizados sem descarregar o domínio de aplicativo. Isso é particularmente útil para aplicativos que devem estar disponíveis continuamente, como sites do ASP.NET.

Importante

Não há suporte para shadow copying em aplicativos da Loja Windows 8.x.

O common language runtime bloqueia um arquivo do assembly quando o assembly é carregado para que o arquivo não possa ser atualizado até que o assembly seja descarregado. A única maneira de descarregar um assembly de um domínio de aplicativo é descarregar o domínio de aplicativo. Portanto, em circunstâncias normais, um assembly não pode ser atualizado no disco até que todos os domínios de aplicativo que o estão usando sejam descarregados.

Quando um domínio de aplicativo é configurado para cópia de sombra de arquivos, os assemblies do caminho do aplicativo são copiados em outro local e carregados a partir desse local. A cópia é bloqueada, mas o arquivo do assembly original é desbloqueado e pode ser atualizado.

Importante

Os únicos assemblies dos quais é possível realizar uma cópia de sombra são aqueles armazenados no diretório do aplicativo ou em seus subdiretórios, especificados pelas propriedades ApplicationBase e PrivateBinPath quando o domínio de aplicativo é configurado. Os assemblies armazenados no cache de assembly global não passam por cópias de sombra.

Este artigo inclui as seções a seguir:

  • Habilitar e usar cópias de sombra descreve o uso básico e as opções disponíveis para cópia de sombra.

  • Desempenho de inicialização descreve as alterações feitas na cópia de sombra no .NET Framework 4 para melhorar o desempenho de inicialização, e como reverter para o comportamento de versões anteriores.

  • Métodos obsoletos descreve as alterações feitas nas propriedades e nos métodos que controlam a cópia de sombra no .NET Framework 2.0.

Habilitando e Usando Cópias de Sombra

Você pode usar as propriedades da classe AppDomainSetup da seguinte forma para configurar um domínio do aplicativo para a cópia de sombra:

  • Habilite a cópia de sombra definindo a propriedade ShadowCopyFiles com o valor de cadeia de caracteres "true".

    Por padrão, essa configuração faz com que todos os assemblies no caminho do aplicativo sejam copiados para um cache de download antes de serem carregados. Esse é o mesmo cache mantido pelo common language runtime para armazenar os arquivos baixados de outros computadores, e o common language runtime exclui automaticamente os arquivos quando eles não são mais necessários.

  • Opcionalmente, defina um local personalizado para os arquivos da cópia de sombra usando as propriedades CachePath e ApplicationName.

    O caminho base para o local é formado pela concatenação da propriedade ApplicationName para a propriedade CachePath como um subdiretório. Assemblies passam por cópia de sombra para subpastas nesse caminho, e não para o caminho base em si.

    Observação

    Se a propriedade ApplicationName não for definida, a propriedade CachePath será ignorada e o cache de download será usado. Nenhuma exceção é gerada.

    Se especificar um local personalizado, você será responsável pela limpeza de diretórios e arquivos copiados quando eles não forem mais necessários. Eles não são excluídos automaticamente.

    Há alguns motivos para você definir um local personalizado para arquivos de cópia de sombra. Talvez você queira definir um local personalizado para os arquivos de cópia de sombra se o aplicativo gerar uma grande quantidade de cópias. O cache de download tem um limite de tamanho, não de tempo de vida, portanto, é possível que o common language runtime tente excluir um arquivo que ainda está em uso. Outro motivo para definir um local personalizado é quando os usuários que estão executando seu aplicativo não tiverem acesso de gravação ao local do diretório usado pelo common language runtime para o cache de download.

  • Opcionalmente, limite os assemblies dos quais é realizada a cópia de sombra usando a propriedade ShadowCopyDirectories.

    Quando você habilita a cópia de sombra para um domínio do aplicativo, o padrão é copiar todos os assemblies no caminho do aplicativo — ou seja, nos diretórios especificados pelas propriedades ApplicationBase e PrivateBinPath. Você pode limitar a cópia aos diretórios selecionados criando uma cadeia de caracteres que contém apenas os diretórios dos quais deseja realizar a cópia de sombra e atribuindo a cadeia de caracteres à propriedade ShadowCopyDirectories. Separe os diretórios com ponto e vírgula. Os únicos assemblies dos quais são feitas cópias de sombra são aqueles nas pastas selecionadas.

    Observação

    Se você não atribuir uma cadeia de caracteres à propriedade ShadowCopyDirectories ou se definir essa propriedade como null, será feita a cópia de sombra de todos os assemblies nos diretórios especificados pelas propriedades ApplicationBase e PrivateBinPath.

    Importante

    Os caminhos de diretório não devem conter ponto e vírgula, pois esse é o caractere delimitador. Não há nenhum caractere de escape para ponto e vírgula.

Desempenho da Inicialização

Quando um domínio de aplicativo que usa a cópia de sombra for iniciado, haverá um atraso durante a cópia dos assemblies do diretório do aplicativo para o diretório de cópia de sombra, ou durante a verificação se eles já estão no local. Antes do .NET Framework 4, todos os assemblies eram copiados para um diretório temporário. Cada assembly era aberto para verificar o nome do assembly, e o nome forte era validado. Cada assembly era analisado para ver se havia sido atualizado mais recentemente do que a cópia no diretório de cópia de sombra. Nesse caso, ele foi copiado para o diretório de cópia de sombra. Por fim, as cópias temporárias eram descartadas.

Do .NET Framework 4 em diante, o comportamento de inicialização padrão é comparar diretamente a data e hora do arquivo de cada assembly no diretório de aplicativo com a data e hora do arquivo da cópia no diretório de cópia de sombra. Se o assembly tiver sido atualizado, ele será copiado usando o mesmo procedimento das versões anteriores do .NET Framework; caso contrário, a cópia no diretório de cópia de sombra será carregada.

A melhoria no desempenho resultante é maior para aplicativos nos quais os assemblies não são alterados com frequência, e as alterações normalmente ocorrem em um pequeno subconjunto dos assemblies. Se a maioria dos assemblies em um aplicativo mudar com frequência, o novo comportamento padrão poderá causar uma regressão do desempenho. Você pode restaurar o comportamento de inicialização de versões anteriores do .NET Framework, adicionando o elemento <shadowCopyVerifyByTimestamp> ao arquivo de configuração, com enabled="false".

Métodos obsoletos

A classe AppDomain tem vários métodos, como SetShadowCopyFiles e ClearShadowCopyPath, que podem ser usados para controlar o shadow copying em um domínio do aplicativo, mas eles foram marcados como obsoletos no .NET Framework versão 2.0. A maneira recomendada de configurar um domínio do aplicativo para a cópia de sombra é usar as propriedades da classe AppDomainSetup.

Confira também