Marshal.Release Exception和正确的清理

时间:2014-07-11 20:06:40

标签: c# .net

我使用以下方法提取文件缩略图。 在这种情况下,如何正确执行清理:DeleteObject(hbitmap);或                 Marshal.Release(hbitmap);

public ImageSource GetThumbnail(string mypath)
{
    IShellItem ppsi = null;
    IntPtr hbitmap = IntPtr.Zero;

    try
    {
        Guid uuid = new Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe");
        SHCreateItemFromParsingName(mypath, IntPtr.Zero, uuid, out ppsi);
        ((IShellItemImageFactory)ppsi).GetImage(new SIZE(128, 128), SIIGBF.SIIGBF_THUMBNAILONLY, out hbitmap);

        BitmapSource source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hbitmap, IntPtr.Zero, Int32Rect.Empty,
        BitmapSizeOptions.FromEmptyOptions());

        return source;
    } 
    catch (Exception ex)
    {
        return null;
    }
    finally
    {               
        if (ppsi != null)                    
            Marshal.ReleaseComObject(ppsi);

        if (hbitmap != IntPtr.Zero)
        {
            DeleteObject(hbitmap); //this
            Marshal.Release(hbitmap); //this 
        }
    }            
}

On Marshal。我得到

  

附加信息:异常被捕获但在处理时处理   通过Marshal释放COM接口指针。释放,   Marshal.ReleaseComObject或隐含后对应   RuntimeCallableWrapper被垃圾收集。这是一个结果   用户引用计数错误或COM对象发布的其他问题。使   确保正确管理refcounts。虽然这些类型的例外   被CLR抓住,它们仍然可能导致腐败和数据丢失   所以如果可能的话,应该解决引起异常的问题

1 个答案:

答案 0 :(得分:1)

Marshal.Release仅用于com对象,而HBITMAP不是一个!你只需要DeleteObject

编辑:正如Hans Passant所提到的,请阅读手册:

  

phbm [out]   键入:HBITMAP *

     

指向一个值,该值在此方法成功返回时接收检索到的位图的句柄。调用者有责任在不再需要时通过DeleteObject释放此检索到的资源。