[英]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.