У меня возникли проблемы с DllImport и ASP.NET, потому что, когда я использую импортированный метод, ASP.NET загружает Dll и блокирует файл даже после его завершения. Есть ли способ заставить ASP.NET освободить блокировку файла?DllImport и ASP.NET
ответ
Единственный способ принудительно вывести DLL из процесса в .Net - это выгрузить AppDomain, в который загружена Dll. Если вы не создадите отдельный AppDomain, в котором запускается код DllImport, это будет невозможно.
Также я знаю, что эта политика применима к управляемым DLL. Я не уверен на 100%, если это относится к загрузке DLL через PINvoke, но я уверен.
Только если вы создали новый AppDomain и загрузили dll в домен. После этого вы можете выгрузить AppDomain, и dll будет выгружена.
Разгрузка 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
, а затем выгрузить его, когда вы закончите.
Для меня это не сработало с добавлением dlls pinvoke. Может зависеть от dll. – Sire