gpt4 book ai didi

c# - SafeFileHandle.Close 抛出异常但句柄有效且有效

转载 作者:太空狗 更新时间:2023-10-29 19:58:42 27 4
gpt4 key购买 nike

我在 WPF 应用程序中遇到自定义游标问题。我使用以下代码创建 Cursor 对象:

[DllImport("user32.dll")]
private static extern IntPtr CreateIconIndirect(ref IconInfo icon);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);

private static Cursor CreateCursor(string cursorName, System.Drawing.Bitmap bmp,
int xHotspot, int yHotspot, out SafeFileHandle handle)
{
IconInfo tmp = new IconInfo();
GetIconInfo(bmp.GetHicon(), ref tmp);
tmp.xHotspot = xHotspot;
tmp.yHotspot = yHotspot;
tmp.fIcon = false;

IntPtr ptr = CreateIconIndirect(ref tmp);
handle = new SafeFileHandle(ptr, true);

if (handle.IsClosed)
{
return null;
}

Cursor cur = CursorInteropHelper.Create(handle);

return cur;
}

当我关闭我的应用程序并且 GC 开始清理垃圾时,它会抛出一个异常:

System.Runtime.InteropServices.SEHException was unhandled
Message=External component has thrown an exception.
Source=mscorlib
ErrorCode=-2147467259
StackTrace:
at Microsoft.Win32.Win32Native.CloseHandle(IntPtr handle)
at Microsoft.Win32.SafeHandles.SafeFileHandle.ReleaseHandle()
at System.Runtime.InteropServices.SafeHandle.InternalDispose()
at System.Runtime.InteropServices.SafeHandle.Dispose(Boolean disposing)
at System.Runtime.InteropServices.SafeHandle.Dispose()
at System.Windows.Input.Cursor.Finalize()
InnerException:

我通过在 if (handle.IsClosed) 上放置断点并使用即时窗口调用 handle.Close() 进行了进一步调查。一些 SafeFileHandle 的关闭很好,其他的则抛出相同的异常 — 在句柄创建后立即。

为了让事情变得有趣, Handlebars 本身也能正常工作。 IsInvalid 为假,IsClosed 为假,光标出现。只是有些句柄永远关不上。

因为我从未打算手动关闭句柄,并且它们只会在应用程序关闭时 Cursor 对象的最终确定期间关闭,所以我可以忽略它们。我没有尝试过 VS2010 之外的发布版本,我不知道这是否会导致出现崩溃对话框。但即使我可以忽略它们,它仍然很乱。

所以基本上我正在寻找任何关于这里可能出现问题的信息,在哪里尝试和调试它......一切似乎都在 native 代码或 GC 中,我无法调试它们中的任何一个。

最佳答案

您将从 CreateIconIndirect 返回的 HICON 包装在 SafeFileHandle 中,释放时调用 CloseHandleHICON 而不是所需的 DestroyIcon 上。不要将 HICON 包装在 SafeFileHandle 中,而是将其包装在自己的专用 SafeHandle 中:

class SafeIconHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DestroyIcon(
[In] IntPtr hIcon);

private SafeIconHandle()
: base(true)
{
}

public SafeIconHandle(IntPtr hIcon)
: base(true)
{
this.SetHandle(hIcon);
}

protected override bool ReleaseHandle()
{
return DestroyIcon(this.handle);
}
}

关于c# - SafeFileHandle.Close 抛出异常但句柄有效且有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9218029/

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