DllImport 和 ASP.NET

发布于 2024-07-16 07:59:16 字数 116 浏览 8 评论 0原文

我在使用 DllImport 和 ASP.NET 时遇到一些问题,因为当我使用导入方法时,ASP.NET 会加载 Dll 并锁定该文件,即使在使用完该文件后也是如此。 有没有办法强制 ASP.NET 释放文件上的锁?

I'm having some problems with DllImport and ASP.NET because when I use a imported method ASP.NET loads the Dll and locks the file even after it finished using it.
Is there any way to force ASP.NET to release the lock on the file?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

太阳哥哥 2024-07-23 07:59:16

在 .Net 中强制 DLL 退出进程的唯一方法是卸载加载该 Dll 的 AppDomain。 除非您创建一个单独的 AppDomain 在其中运行 DllImport 代码,否则这是不可能的。

我还知道此策略适用于托管 DLL。 我不能 100% 确定这是否适用于通过 PINvoke 加载的 DLL,但我相当确定。

The only way to force a DLL out of the process in .Net is to unload the AppDomain in which the Dll is loaded. Unless you create a separate AppDomain in which run the DllImport code this will not be possible.

Also I know this policy applies to managed DLL's. I am not 100% sure if this applies to DLL's loaded via PINvoke but I am fairly certain.

ま昔日黯然 2024-07-23 07:59:16

仅当您创建新的 AppDomain 并将 dll 加载到域中时。 然后你可以卸载AppDomain,dll也会被卸载。

Only if you create a new AppDomain and load the dll into the domain. Afterwards you can unload the AppDomain and the dll will be unloaded.

猥琐帝 2024-07-23 07:59:16

卸载 AppDomain 并不是唯一的答案。 您还可以通过 pinvoke 使用 LoadLibraryFreeLibrary 来卸载库。 只需确保您调用 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 中执行任何操作,然后在完成后将其卸载。

Unloading the AppDomain is not the only answer. You can also use LoadLibrary and FreeLibrary over pinvoke to unload the library. Just make sure you're calling FreeLibrary twice to ensure any dependencies of your library get unloaded as well.

I haven't tested this, but I imagine a class like this would make doing this easier:

[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);
        }
    }
}

Just be warned that this example is not thread safe, which you'll want to guarantee in ASP.NET, and doesn't do complete error checking.

Also, as this may violate some assumptions made by the runtime, using FreeLibrary on a library you didn't load may not be a good idea.

Another alternative would be to perform whatever operation in a new AppDomain and then unload it when you are done.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文