我可以使用.NET SafeHandle类并确定性地释放其中的句柄吗? - c#

我有一个.NET项目,我在运行时根据平台的位性从资源中提取一个本机代码.DLL,其中包含我需要使用的功能。我使用LoadLibrary,GetProcAddress和FreeLibrary在托管代码中管理库的加载和使用。

在完成本机库之后,我想将其删除。这是一些伪代码,显示了当前实现的工作流程:

internal class MyClass()
{    
    string nativeLibraryPath = "C:\my\path\to\extracted\library.dll";
    IntPtr nativeLibraryHandle = IntPtr.Zero;

    public void Load()
    {
        nativeLibraryHandle = NativeMethods.LoadLibrary(nativeLibraryPath);
    }

    public void ExecuteFunction()
    {
        IntPtr functionPointer = NativeMethods.GetProcAddress(nativeLibraryHandle, "MyFunctionName");
        // assume MyManagedDelegate is defined as the correct delegate type.
        MyManagedDelegate managedFunction = Marshal.GetDelegateForFunctionPointer(functionPointer, typeof(MyManagedDelegate)) as MyManagedDelegate;
        managedFunction("foo", "bar");
    }

    public void Unload()
    {
        NativeMethods.FreeLibrary(nativeLibraryHandle);
        File.Delete(nativeLibraryPath);
    }
}

使用类型为IntPtr的变量时,此方法工作正常。普遍的智慧(最佳实践?)表明,SafeHandle可能是一种更好的方法。但是,我的理解是,在使用SafeHandle时,不会确定性地调用ReleaseHandle()方法。也就是说,在SafeHandle上调用Close()或Dispose()方法仅将类标记为垃圾回收;在对象被收集之前,它不会调用ReleaseHandle。这对我来说是个问题,因为在卸载本机代码.DLL之前,我无法删除它。如果我在ReleaseHandle期间调用FreeLibrary,该如何确定性地等待该库被释放(而无需借助诸如调用GC.Collect()之类的黑客手段)?

编辑我已经更新了该示例,以更能代表我的实际代码的结构。请注意,此示例中发布的代码不完整。我在生产代码中包括必要的错误检查和异常处理。

参考方案

不,那是不正确的。当您的代码忘记这样做时,SafeHandle负责释放该句柄。只有在终结器线程上运行的代码才能确定性地发生这种情况。调用Dispose()具有高度确定性。

您编写的代码并不安全,当发生异常时,它将永久泄漏模块句柄。您应该使用finally块来确保释放句柄。这已经足够好了,这里不需要SafeHandle,因为您将句柄保留为局部变量,并且始终可以确定性地释放它。

jQuery发布不会将数据发布到ASP.NET API控制器 - javascript

我有一次噩梦般的时间通过jquery post将数据发送到ASP.NET Controller。这是JSON.stringify之后的数据:[{"scheduleTaskID":"203","task":"Permit","baselineDate":…

.NET C#Webbrowser填充输入,不带ID或类名 - javascript

我需要在网络浏览器中填写一个输入,但这不起作用。我认为必须使用name属性来完成,但是怎么做呢?foreach (HtmlElement login in webBrowser1.Document.GetElementsByTagName("input")) { if (login.GetAttribute("name"…

从JAVA调用方法C#.NET - java

我有一个C#.NET项目中创建的dll,我想从Java程序中调用方法。我想知道是否存在实现此目标的机会,然后遇到了JNA和JNI。我应该使用哪一个?有什么建议么?我只需要在使用C#.NET编写的类中调用方法并处理Java程序的结果即可。 参考方案 这取决于您的应用程序,但是您可以将C#DLL放在服务中,例如WCF并以这种方式将功能公开给Java代码。使用ws…

ddl在服务器中未更新-asp.net - javascript

我在ASP.NET c#上工作。我有一个DropDownList。 (runat =“ server”)在$ {document).ready上,我更新了它的值:$(document).ready(function () { document.getElementById("ddl").value = "abc"; ……

asp.net mvc中的对象数组数据始终为null - javascript

我需要通过json将对象数组发送到asp.net mvc 2,但是我在mvc控制器中没有得到null对象是这样的entries[1].date = "12/22/2014" entries[1].Ref = "0002" entries[1].Credit = "100" entries[2].da…