インポートされたメソッドを使用すると、ASP.NET が Dll をロードし、使用が終了した後でもファイルをロックするため、DllImport と ASP.NET で問題が発生しています。ASP.NET にファイルのロックを強制的に解除させる方法はありますか?
3 に答える
DLLを.Netのプロセスから強制的に除外する唯一の方法は、DLLがロードされているAppDomainをアンロードすることです。DllImportコードを実行する別のAppDomainを作成しない限り、これは不可能です。
また、このポリシーがマネージDLLに適用されることも知っています。これがPINvokeを介してロードされたDLLに適用されるかどうかは100%わかりませんが、かなり確信しています。
新しいAppDomainを作成し、そのdllをドメインにロードする場合のみ。その後、AppDomainをアンロードすると、dllがアンロードされます。
AppDomain をアンロードすることが唯一の答えではありません。LoadLibrary
とFreeLibrary
over pinvoke を使用してライブラリをアンロードすることもできます。FreeLibrary
ライブラリの依存関係もアンロードされるように、2 回呼び出していることを確認してください。
私はこれをテストしていませんが、このようなクラスがこれをより簡単にするだろうと思います:
[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
ため、ロードしていないライブラリで使用することはお勧めできません。
もう 1 つの方法は、new で任意の操作を実行し、AppDomain
完了したらアンロードすることです。