簡體   English   中英

SafeFileHandle.Close拋出異常,但句柄有效且有效

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM