Os servidores Windows (2008) armazenam em cache assemblies .net de alguma forma?

2

Um colaborador meu está tendo o seguinte problema (portanto, alguns detalhes relevantes podem exigir uma avaliação mais detalhada):

O servidor é o Windows 2008 Server. Existe um serviço do Windows em execução (exe (.net), que também utiliza um assembly .NET). Há algum bug com a dll e / ou exe. Algumas mensagens de depuração foram adicionadas e removidas da dll. Esta nova versão da dll e do seu exe recompilado foram transferidos para este servidor, o serviço foi parado, a dll e o exe existentes foram renomeados e substituídos pelo novo, e o serviço foi iniciado.

Ainda vemos mensagens de depuração que foram removidas da dll. Eles não existem no novo código.

O servidor foi reiniciado.

A dll antiga está sendo armazenada em algum lugar? de alguma forma? Obrigado.

UPDATE

O seguinte aconteceu:

  1. o assembly.old renomeado recentemente foi removido fisicamente (essa foi a única cópia)
  2. mensagens de depuração antigas ainda estão lá!
  3. serviço desinstalado / reinstalado (embora acreditemos que poderíamos ter conseguido uma reinicialização)
  4. funciona.

Então, sabendo o que aconteceu antes disso (que incluiu uma reinicialização do sistema operacional), e o que aconteceu agora, o Windows está rastreando a dll (?) e quando uma cópia foi renomeada, o Windows desafia a atualização e os associados (em mente) que assembly.old será assembly.dll. Não o novo assembly.dll que foi colocado em seu lugar?

Porque assembly.dll e assembly.old no mesmo diretório, após a reinicialização do sistema operacional - antiga dll continuamente olhou. assembly.dll e não assembly.old - funciona.

O que me deixa perplexo é como você controla isso? Ou onde está a documentação sobre isso?

Outras informações: versão de 64 bits do servidor. Uma VM.

    
por JustLooking 04.01.2012 / 17:29

2 respostas

3

Isso pode ser devido a como o .NET localiza assemblies, documentados aqui:

Como o .NET Runtime localiza Assemblies
link

Observe o seguinte:

"O compilador registra referências estáticas nos metadados do manifesto do assembly no momento da compilação. As referências dinâmicas são construídas dinamicamente como resultado da chamada de vários métodos, como System.Reflection.Assembly.Load."

Se sua referência é estática, você pode examinar os metadados do assembly em execução para o manifesto. O manifesto pode ser examinado usando o ILDASM ou alguma outra ferramenta como o ILSpy. Se for dinâmico, o processo de localização é complexo e sofisticado.

Minha experiência tem sido que, se existem várias versões do CLR (por exemplo, 2.0 e 4.0), o resultado pode ser inesperado. Existem vários fatores adicionais, como:

  • configuração da máquina e configuração da aplicação;
  • se o aplicativo é todo código gerenciado ou possui algum código não gerenciado (COM / Interop);
  • se a montagem de execução / chamada e assemblies chamados forem independentes de plataforma ("qualquer cpu") ou específica de plataforma (x86 ou x64).

Também é possível executar o código CLR 2.0 e 4.0 em um processo ao mesmo tempo (execução lado-a-lado).

Eu acho que isso deve ser reproduzível em um ambiente de desenvolvimento, e não é realista esperar que o consumidor saiba ou lide com todos os cenários possíveis.

Execução lado-a-lado no processo .NET
link

Assemblies: localização, vinculação e implantação do link

Quando você executa o Process Explorer do Microsoft SysInternals, seleciona o processo do serviço e a guia .NET Assemblies, ele deve mostrar todos os vários assemblies carregados para que você possa validar se o arquivo correto está carregado:

    
por 04.01.2012 / 20:28
1

Bem, você respondeu sua própria pergunta lá. Você deixou cair uma nova DLL em seu disco, mas quando você executa algum código ainda parece estar usando a DLL antiga. Portanto, deve haver uma cópia da DLL antiga ainda em sua memória em algum lugar.

Tente isso: crie um atalho e use-o como o comando a ser executado:

% windir% \ system32 \ rundll32.exe advapi32.dll, ProcessIdleTasks

Nomeie o que você quiser ... algo como "Flusher de cache de memória". Execute-o entre as execuções de teste do seu programa.

    
por 04.01.2012 / 20:12