2014-07-21 8 views
5

하루에 한 번 실행되는 Windows 서비스가 있습니다. 그것은 단지 10 분의 행동입니다.dll 파일 잠금없이 .NET 어셈블리 사용

서비스가 웹 사이트 dll을 사용하기 때문에 서비스의 파일을 웹 사이트의 bin 폴더에 만듭니다.

불행히도 웹 사이트 모듈 (dotnetnuke .zip 모듈을 웹 사이트 설치 프로그램으로 설치)을 설치했을 때 파일이 앤서 프로세스에 의해 잠겨 있다는 오류가 나타났습니다.

각 모듈이 설치되기 전에 서비스를 사용하지 않도록 설정하면 서비스에 사용되는 DLL을 잠그지 않고 서비스를 만들고 싶습니다.

AppDomain 및 ShadowCopyFiles 옵션에 대해 읽었지만 제대로 작동하지 않습니다. 예를 들어, 어셈블리의

class Program 
{ 
    static string GenerateRandomName() 
    { 
     //maybe name must be unique?! 
     var random = new Random(); 
     return "a" + random.Next().ToString() + "b" + random.Next(); 
    } 

    static int RandomNumber() 
    { 
     var info = ConfigureAppDomainSettings(); 

     var domain = AppDomain.CreateDomain(GenerateRandomName(), null, info); 
     var assembly = domain.Load("SharedLibrary"); 
     var shared = (SharedLibrary.IShared)assembly.CreateInstance("SharedLibrary.Shared"); 

     int retVal = shared.RandomNumber(); 

     AppDomain.Unload(domain); 

     domain = null; 
     assembly = null; 
     shared = null; 
     info = null; 

     Console.WriteLine("before cleanning"); 
     GC.Collect(); 
     GC.WaitForPendingFinalizers(); 
     GC.Collect(); 
     GC.WaitForFullGCComplete(); 
     GC.Collect(); 
     Console.WriteLine("after cleanning"); 

     return retVal; 
    } 

    static AppDomainSetup ConfigureAppDomainSettings() 
    { 
     AppDomainSetup domainSettings = AppDomain.CurrentDomain.SetupInformation; 
     domainSettings.ShadowCopyFiles = "true"; 
     domainSettings.CachePath = @"C:\inetpub\wwwroot\eshop\DesktopModules\Rossnet_EShop\SharedAssemblyTest\PrivateCache"; 

     return domainSettings; 
    } 

    static void Main(string[] args) 
    { 
     Console.WriteLine(RandomNumber()); 

     Console.ReadKey(); 
    } 
} 

코드 :

내가 ShadowCopyFiles를 사용하는 방법의 예입니다

public interface IShared 
{ 
    int RandomNumber(); 
} 

[Serializable] 
public class Shared : IShared 
{ 
    public int RandomNumber() 
    { 
     var random = new Random(); 
     return random.Next(20); 
    } 
} 

개인 캐시가 작성되지 잠겨 원본 파일이 잠겨 있습니다. < - 지금 당장이 일은 터무니 없습니다.

+0

IShared 인터페이스가 두 appdomains에로드됩니다. DLL에 영구 잠금을 설정합니다. Shared 클래스를 다른 클래스에 넣으십시오. –

+0

이전에 인터페이스 대신 동적 유형으로 변환했는데 작동하지 않아 내 코드에서만 문제가되지 않습니다. –

답변

8

어셈블리를 사용하는 모든 코드를 수정할 수있는 액세스 권한이있는 경우 Assembly.Load 과부하로로드하면 byte[] 걸리는 트릭을 수행해야합니다. 파일을 직접 읽고 그 방법으로 전달합니다. 필자는이 방법을 직접 사용합니다 (다른 이유로도 가능). 언제든지 파일을 업데이트 할 수 있습니다.

이 작업을 쉽게 수행 할 수있는 방법은 파일 이름을 .dll에서 다른 것으로 변경하여 찾을 수 없으므로 AppDomain.AssemblyResolve 이벤트에 가입하는 것입니다. 그것들은 누락되어 있습니다. 그 시점에서 어셈블리를 수동으로로드하는 코드를 가질 수 있습니다.