gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 23:00:23 25 4
gpt4 key购买 nike

我有一个 .NET 项目,在该项目中,我在运行时根据平台位数从资源中提取了一个 native 代码 .DLL,其中包含我需要使用的函数。我使用 LoadLibrary、GetProcAddress 和 FreeLibrary 来管理托管代码中库的加载和使用。

使用完 native 库后,我想将其删除。下面是一些伪代码,显示了当前实现的工作流程:

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。这对我来说是个问题,因为在卸载之前我无法删除我的 native 代码 .DLL。如果我在 ReleaseHandle 期间调用 FreeLibrary,我如何才能确定地等待库被释放(不求助于 hackery,例如调用 GC.Collect())?

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

最佳答案

不,这不准确。当您的代码忘记这样做时,SafeHandle 负责释放句柄。只有 that 会非确定性地发生,在终结器线程上运行的代码。调用 Dispose() 是高度确定性的。

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

关于c# - 我可以使用 .NET SafeHandle 类并确定性地释放其中的句柄吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4828939/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com