[英]SafeFileHandle.Close throws an exception but the handle is valid and works
我在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
的关闭很好,其他人抛出相同的异常 - 在创建句柄后立即执行。
只是为了让事情变得有趣,手柄本身也很好用。 IsInvalid
为false, IsClosed
为false,并且显示游标。 只是有些句柄永远不会被关闭。
因为我从不打算手动关闭句柄,并且只有在应用程序关闭时完成Cursor
对象的过程中才会关闭它们,我可能只能忽略它们。 我没有在VS2010之外尝试过Release版本,我不知道是否会导致出现崩溃对话框。 但即使我可以忽略它们,它仍然是凌乱的。
所以基本上我正在寻找关于这里可能出现什么问题的任何信息,在哪里寻找尝试和调试这一切...一切似乎都在本机代码或GC中,我无法调试任何它。
你将从CreateIconIndirect
返回的HICON
包装在一个SafeFileHandle
中,它在释放时调用HICON
上的CloseHandle
而不是所需的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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.