DllImport и ASP.NET - PullRequest
       11

DllImport и ASP.NET

4 голосов
/ 07 апреля 2009

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

Ответы [ 3 ]

2 голосов
/ 07 апреля 2009

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

2 голосов
/ 07 апреля 2009

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

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

0 голосов
/ 01 апреля 2015

Выгрузка домена приложения - не единственный ответ. Вы также можете использовать 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, а затем выгрузка его после завершения.

...