在使用GDI+时,下面的几个问题值得注意:
一、Pen::GetBrush存在内存泄露。MSDN上对Pen::GetBrush函数给出了一段示例代码:
在该代码中并没有释放由GetBrush函数返回的Brush对象所占的内存空间。但是在实际使用的过程中发现,随着这个函数调用次数的增加,程序所占的内存也逐渐增加,而当换用另外的方式获得Brush对象时(例如声明一个局部的SolidBrush对象),程序的内存使用量不再存在显著的增加。
二、这个问题在一个项目中遇到过,不过到现在还不知道具体原因。具体情况是:在一个使用了GDI+的工程中,一个处理数据的工作线程在循环中处理数据并且将数据设置到界面并且调用界面的RedrawWindow函数。但是在程序退出的时候,使用WaitforSingleObject函数等待此线程退出时出现超时,程序失去响应。
该程序的线程数不多,可以排除自己在编码过程中形成的死锁所造成的程序死机问题。在Visual Studio中调试时强制中断后发现,调用堆栈的顶端是一个由Gdiplus.dll中的函数引发的Wait×××函数,因此怀疑是GDI+中的某些机制与程序本身使用的WaitforSingleObject函数形成了某种死锁。而要消除这种死锁,必须让界面线程有机会处理消息(不在WaitforSingleObject上卡死)。
最后的解决办法是,在一个自定义的消息循环中等待句柄发出信号,这样程序可以成功等待句柄发出信号(即工作线程退出)。部分代码如下:
其中MsgWaitForHandle函数如下:
这个问题还有另外一种解决办法,即另外设置一个工作线程,该线程的任务只有一个,就是等待一个句柄发出信号,经过尝试这种方法也能解决上面遇到的问题。