2012-05-31 81 views
3

我刚刚将我的项目的目标框架从.NET 3.5更改为.NET 4.0,以从新功能中受益。但现在,当我开始我的计划,我得到:将项目从.NET 3.5移动到.NET 4.0:突然释放处理失败

一个的SafeHandle或类型的CriticalHandle“BitmapHandle”未能正确 释放与价值0xB605123D手柄。这通常 表明该句柄通过其他手段 发布不正确(如提取使用DangerousGetHandle手柄,直接关闭它 或另建SafeHandle的周围。)

但我甚至不知道在哪里开始寻找原因,我没有得到任何更多的信息,并在3.5一切都很好。

+0

我也有这个错误,以及迁移到4.0后。你找到了解决方案? – joerage

+3

我发现在我的情况下它与启动屏幕有关。如果我没有启动闪屏,错误消失。 – joerage

+0

你说得对,对我来说也是一样。虽然很奇怪......我现在删除了启动画面。 – metacircle

回答

3

这是WPF SplashScreen类中的一个错误。不过在周围.NET 4.6 BitmapHandle是的SafeHandle类,其ReleaseHandle()方法是这样的:

protected override bool ReleaseHandle() 
    { 
     return UnsafeNativeMethods.DeleteObject(handle); 
    } 

这是相当正确的,它保证了GDI位图对象正确销毁无论发生什么事情。该缺陷存在于SplashScreen.DestroyResources()方法,它可以帮助太多:

private void DestroyResources() 
    { 
     //... 
     if (_hBitmap != null && !_hBitmap.IsClosed) 
     { 
      UnsafeNativeMethods.DeleteObject(_hBitmap.MakeHandleRef(null).Handle); 
      _hBitmap.Close(); 
      _hBitmap = null; 
     } 
     //... 
    } 

两个呼叫DeleteObject,这是太多了。调试器有一个MDA(托管调试助手),监视这样的错误,它看到ReleaseHandle()失败并进入。你通常不会看到这个,因为(不明智)MDA默认关闭。调试>例外>托管调试助手> ReleaseHandleFailed。取消它以停止获取通知。

像这样的错误是非常讨厌的,他们打开了处理回收攻击的大门。然而,实际可利用的可能性非常低,Close()调用紧跟在DeleteObject()调用之后,并且位图不是特别危险:)事故在技术上是可行的,您必须有另一个线程创建GDI对象时间,这并不经常发生在WPF应用程序中。

你可以在connect.microsoft.com上提交错误,这个Q + A的链接应该足够了。

相关问题