c#

位置:IT落伍者 >> c# >> 浏览文章

.Net程序开发中一个较为隐蔽的GDI洩露探析收藏


发布日期:2018年07月18日
 
.Net程序开发中一个较为隐蔽的GDI洩露探析收藏

最近一直在调试第三方委托开发的医疗输液系统(我接手时代码已经完成原则上我只修改接口部分以适应我们的硬件即可不过调试过程中该程序本身问题暴露不少)该系统用开发该软件的图形界面是花费n多银子专门做的美工大量的贴图就是目前的主流PC机配置也很难在调试模式下走顺溜

问题出在两方面第一存在内存洩露(有时间我专门为此写篇文章)第二存在GDI洩露

最早的时候由于存在内存洩露问题我一直以为windows弹出的GDI一般性错误是由于内存洩露引起的直到内存问题得以解决程序还是运行一段时间就弹出类似错误查了很多资料发现windows任务管理器可以查看GDI是否洩露

发现该程序的GDI对象计数猛涨由于没有很好的GDI检查工具和方法(如果这方面有高手希望不吝指教)所以我对程序中大段大段涉及GDI的代码进行屏蔽然后再检查是否GDI有洩露n次重复后功夫不负有心人终于锁定罪魁祸首相关代码如下

Select Case (uPumpDataPumpName & )Trim

Case ******

IRBDetailIcon = IconFromHandle(CType(ImgTabPageImages() Bitmap)GetHicon)

Case XXXXXX

IRBDetailIcon = IconFromHandle(CType(ImgTabPageImages() Bitmap)GetHicon)

Case Else

IRBDetailIcon = Nothing

End Select

问题就出在 IconFromHandle(CType(ImgTabPageImages() Bitmap)GetHicon)这句代码上msdn在关键时刻不辱使命一查结果真相大白

IconFromHandle 方法

从图标的指定 Windows 句柄 (HICON) 创建 GDI+ Icon

命名空间:SystemDrawing

程序集:SystemDrawing(在 systemdrawingdll 中)

Visual Basic(声明)

Public Shared Function FromHandle (handle As IntPtr ) As Icon

Visual Basic(用法)

Dim handle As IntPtr

Dim returnValue As Icon

returnValue = IconFromHandle(handle)

参数

handle 图标的 Windows 句柄

返回值

此方法创建的 Icon

备注

使用此方法时必须使用 Win API 中的 DestroyIcon 方法释放产生的图标以确保释放相应资源

示例

下面的代码示例设计用于 Windows 窗体它需要 PaintEventArgse(这是 Paint 事件处理程序的参数)代码执行下列操作

· 创建一个 Bitmap

· 将该对象绘制到屏幕

· 获取 Bitmap 的图标句柄

· 将窗体的 FormIcon 属性设置为从该句柄创建的图标

· 调用 Win API 函数 DestroyIcon 以释放资源

_

Private Shared Function DestroyIcon(ByVal handle As IntPtr) As Boolean

End Function

Private Sub GetHicon_Example(ByVal e As PaintEventArgs)

Create a Bitmap object from an image file

Dim myBitmap As New Bitmap(c:\FakePhotojpg)

Draw myBitmap to the screen

eGraphicsDrawImage(myBitmap )

Get an Hicon for myBitmap

Dim HIcon As IntPtr = myBitmapGetHicon()

Create a new icon from the handle

Dim newIcon as Icon = SystemDrawingIconFromHandle(HIcon)

Set the form Icon attribute to the new icon

MeIcon = newIcon

Destroy the icon since the form creates its

own copy of the icon

DestroyIcon(newIconHandle)

End Sub

注意备注很关键要用API DestroyIcon释放相关对象

我声明了一个API函数

Public Declare Function DestroyIcon Lib user Alias DestroyIcon (ByVal hIcon As Integer) As Integer

在IRBDetailIcon的属性代码中添加了如下代码问题立马解决(当然类销毁的代码中

m_Icon也要释放一下)

Public Property Icon() As Icon

Get

Return m_Icon

End Get

Set(ByVal Value As Icon)

叶帆

If Not IsNothing(m_Icon) Then

DestroyIcon(m_IconHandle)

m_IconDispose()

m_Icon = Nothing

End If

m_Icon = Value

MeInvalidate()

End Set

End Property

千里之堤溃于蚁穴几万行的代码就坏在这一点上实在值得人警惕!

上一篇:C#委托的同步调用和异步调用

下一篇:微软预览Visual Studio新版Orcas新功能