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


2

Um colega meu está com o seguinte problema (alguns detalhes relevantes podem exigir mais exames):

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 erro com a dll e / ou exe. Algumas mensagens de depuração foram adicionadas e removidas da DLL. Essa nova versão da dll e seu exe recompilado foram transferidos por ftp para esse 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 removidas da DLL. Eles não existem no novo código.

O servidor foi reiniciado.

A dll antiga está ficando em cache em algum lugar? de alguma forma? Obrigado.


ATUALIZAR

Aconteceu o seguinte:

  1. o assembly.old recentemente renomeado 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 pensemos que poderíamos ter escapado com uma reinicialização)
  4. trabalho.

Portanto, sabendo o que aconteceu antes disso (que incluía uma reinicialização do sistema operacional) e o que aconteceu agora, de alguma forma / de alguma maneira o Windows está rastreando as dlls (?) E quando a cópia foi renomeada, o Windows desafia a atualização e os associados (na sua 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 SO - dll antiga continuamente olhou. assembly.dll e nenhum 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.

Respostas:


3

Isso pode ser devido à maneira como o .NET localiza os assemblies, documentados aqui:

Como o .NET Runtime localiza assemblies
http://msdn.microsoft.com/en-us/library/yx7xezcf%28v=VS.100%29.aspx

Observe o seguinte:

"O compilador registra referências estáticas nos metadados do manifesto do assembly no momento da criaçã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 for estática, você poderá 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 foi que, se existirem 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 de aplicativos;
  • se o aplicativo é todo código gerenciado ou possui algum código não gerenciado (COM / Interop);
  • se o assembly de execução / chamada e os assemblies chamados são independentes da plataforma ("qualquer CPU") ou específicos da 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 conheça ou lide com todos os cenários possíveis.

Execução lado a lado do .NET .NET
http://msdn.microsoft.com/en-us/library/ee518876%28VS.100%29.aspx

Assemblies: localizando, vinculando e implantando
http://www.codeproject.com/KB/install/assemblydeployment.aspx

Ao executar o Process Explorer do Microsoft SysInternals, selecione o processo de 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 foi carregado:

insira a descrição da imagem aqui


1

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

Tente isso - crie um atalho e use isso como o comando para executar:

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

Nomeie o que quiser ... algo como "Memory Cache Flusher". Execute-o entre as execuções de teste do seu programa.


Bem, a única cópia da DLL foi renomeada para .old. E nós reiniciamos. Sugeri que ele apenas o removesse completamente. Independentemente de saber se isso o corrige ou não, estou confuso sobre como o Windows agora 'percebe' o fato de que blah.old é blah.dll. E por que ele ignora o verdadeiro (novo) blah.dll! E isso é algo que pode ser controlado de alguma forma? Parece algo estranho no Windows que pode causar muitos soluços, e não estou encontrando muitas informações no Google-land. Vou jogar seu comentário do jeito dele. Muito obrigado, agradeço.
usar o seguinte código
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.