相关疑难解决方法(0)

GDI在第二个线程中使用TGIFImage处理泄漏

我有一个后台线程加载图像(从磁盘或服务器),目标是最终将它们传递给主线程进行绘制.当第二个线程使用VCL TGIFImage加载GIF图像时,每次在线程中执行以下行时,此程序有时会泄漏几个句柄:

m_poBitmap32->Assign(poGIFImage);
Run Code Online (Sandbox Code Playgroud)

也就是说,刚刚打开的GIF图像被分配给线程拥有的位图.这些都不与任何其他线程共享,即完全本地化到线程.它与时序有关,因此每次执行该行时都不会发生,但是当它确实发生时,它只发生在该行上.每个泄漏都是一个DC,一个调色板和一个位图.(我使用GDIView,它提供比Process Explorer更详细的GDI信息.) m_poBitmap32这是一个Graphics32 TBitmap32对象,但我使用普通的VCL专用类重现了这一点,即使用Graphics::TBitmap::Assign.

最终我得到一个EOutOfResources异常,可能表明桌面堆已满:

:7671b9bc KERNELBASE.RaiseException + 0x58
:40837f2f ; C:\Windows\SysWOW64\vclimg140.bpl
:40837f68 ; C:\Windows\SysWOW64\vclimg140.bpl
:4084459f ; C:\Windows\SysWOW64\vclimg140.bpl
:4084441a vclimg140.@Gifimg@TGIFFrame@Draw$qqrp16Graphics@TCanvasrx11Types@TRectoo + 0x4a
:408495e2 ; C:\Windows\SysWOW64\vclimg140.bpl
:50065465 rtl140.@Classes@TPersistent@Assign$qqrp19Classes@TPersistent + 0x9
:00401C0E TLoadingThread::Execute(this=:00A44970)
Run Code Online (Sandbox Code Playgroud)

如何TGIFImage在后台线程中解决此问题并安全使用?

其次,我会遇到PNG,JPEG或BMP类的同样问题吗?我还没有到目前为止,但鉴于它是一个线程/时间问题并不意味着如果他们使用相似的代码我就不会TGIFImage.

我正在使用C++ Builder 2010(RAD Studio的一部分.)


更多细节

一些研究表明,我不是唯一遇到这种情况的人.引用一个帖子,

Help(2007)说:在使用Lock保护画布的多线程应用程序中,所有使用画布的调用都必须通过调用Lock来保护.在使用之前没有锁定画布的任何线程都会引入潜在的错误.

[...]

但是这个陈述是绝对错误的:即使其他线程没有触摸它,你也必须在辅助线程中锁定画布.否则,画布的GDI句柄可以在主线程中随时释放(异步).

另一个回复表明类似的东西,它可能与graphics.pas中的GDI对象缓存有关.

这很可怕:在一个线程中完全创建和使用的对象可以在主线程中异步释放一些资源.不幸的是,我不知道如何应用Lock建议TGIFImage. TGIFImage没有Canvas,虽然它确实有Bitmap一个画布.锁定无效.我怀疑这个问题实际上是TGIFFrame一个内部课程.我也不知道是否或如何锁定任何TBitmap32资源.我确实尝试将TMemoryBackend位图分配给位图,这避免了使用GDI,但它没有任何效果.

再生产 …

delphi memory-leaks gdi c++builder thread-safety

16
推荐指数
1
解决办法
1560
查看次数

主线程繁忙时在Delphi中显示启动画面

我想在加载应用程序时显示启动画面.但是,某些第三方组件在启动期间会阻塞主线程几秒钟,这会导致所有表单都不更新.是否可以使用自己的线程启动屏幕,这样当主线程忙时它也会更新?

该应用程序是win32和Delphi 2007版.

编辑:我正在尝试避免"未绘制的启动画面"效果,如果某些其他窗口(来自其他应用程序)位于启动画面的顶部,例如alt-tabbing到另一个应用程序并返回,则会发生这种情况.

delphi multithreading splash-screen delphi-2007

12
推荐指数
2
解决办法
1万
查看次数

如何在后台从多个线程加载图像[多个线程] [又名:TBitmap不是线程安全的]

我想快速显示一些图像(jpg,png等)作为缩略图.因为解码和调整大小过程是懒惰的,所以我要在一个或多个线程中完成它.

但是,看起来使用TBitmap的画布并且TJpeg不是多线程安全的.

在这种情况下,我的问题是:
1.如果不完全重写GIF/PNG/BMP/JPG库,怎么办呢?
2.有人知道Embarcadero的Gif和Png libs是否也不安全?
3.如果我使用Lock锁定画布不会破坏性能,因为调整大小部分访问画布并占用大部分CPU周期?


我发现这让我很烦恼:

David HAROUCHE写道:这不正确.真正令人困惑的部分是,即使本地TBitmap不是线程安全的,除非你锁定它们.这是因为每个TBitmap都将自己注册到graphics.pas中的全局BitmapCanvasList列表.当DC垃圾收集FreeMemoryContexts()

http://www.codenewsfast.com/cnf/thread/0/permalink.thr-ng1908q2024

delphi

4
推荐指数
1
解决办法
2856
查看次数