2009-04-07 5 views
3

У меня возникли проблемы с DllImport и ASP.NET, потому что, когда я использую импортированный метод, ASP.NET загружает Dll и блокирует файл даже после его завершения. Есть ли способ заставить ASP.NET освободить блокировку файла?DllImport и ASP.NET

ответ

2

Единственный способ принудительно вывести DLL из процесса в .Net - это выгрузить AppDomain, в который загружена Dll. Если вы не создадите отдельный AppDomain, в котором запускается код DllImport, это будет невозможно.

Также я знаю, что эта политика применима к управляемым DLL. Я не уверен на 100%, если это относится к загрузке DLL через PINvoke, но я уверен.

+0

Для меня это не сработало с добавлением dlls pinvoke. Может зависеть от dll. – Sire

2

Только если вы создали новый AppDomain и загрузили dll в домен. После этого вы можете выгрузить AppDomain, и dll будет выгружена.

0

Разгрузка AppDomain - не единственный ответ. Вы можете также использовать LoadLibrary и FreeLibrary над pinvoke, чтобы выгрузить библиотеку. Просто убедитесь, что вы вызываете FreeLibrary дважды, чтобы гарантировать, что любые зависимости вашей библиотеки также будут выгружены.

Я не проверял, но я представить себе класс, как это сделало бы сделать это проще:

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
private static extern IntPtr LoadLibrary(string libname); 

[DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
private static extern bool FreeLibrary(IntPtr hModule); 

class LibraryHandle 
{ 
    readonly string libName; 
    int refCount = 0; 
    IntPtr handle; 

    public LibraryHandle(string name) 
    { 
     libName = name; 
    } 

    public void Increment() 
    { 
     if (refCount == 0) 
     { 
      handle = LoadLibrary(libName); 
      if (Handle == IntPtr.Zero) 
      { 
       int error = Marshal.GetLastWin32Error(); 
       throw new Exception(string.Format("{0})", error)); 
      } 
     } 
     ++refCount; 
    } 

    public void Decrement() 
    { 
     if (refCount <= 0) 
      return; 

     if (--refCount) 
     { 
      // It might be better in some cases to: 
      // while(FreeLibrary(handle)); 
      FreeLibrary(handle); 
      FreeLibrary(handle); 
     } 
    } 
} 

Просто имейте в виду, что этот пример не Потокобезопасная, который вы хотите гарантии в ASP.NET и не выполняет полную проверку ошибок.

Кроме того, поскольку это может нарушить некоторые допущения, сделанные во время выполнения, использование FreeLibrary в библиотеке, которую вы не загрузили, может быть не очень хорошая идея.

Другим вариантом было бы выполнить любую операцию в новом AppDomain, а затем выгрузить его, когда вы закончите.