如果许多异步线程在一个全局 TBitmap 中绘制,它会给我一个错误?我应该使用关键部分创建我的代码吗?(我在网上冲浪时发现 TBitmap.Draw 不是线程安全的)
另一个问题:如果许多同步线程在全局 TBitmap 中绘制,而 VCL Timer 从 TBitmap 异步读取内容,这会引发错误吗?
谢谢!
如果许多异步线程在一个全局 TBitmap 中绘制,它会给我一个错误?我应该使用关键部分创建我的代码吗?(我在网上冲浪时发现 TBitmap.Draw 不是线程安全的)
另一个问题:如果许多同步线程在全局 TBitmap 中绘制,而 VCL Timer 从 TBitmap 异步读取内容,这会引发错误吗?
谢谢!
是的,您确实需要保护TBitmap
跨多个线程的并发访问。关键部分可以序列化您的绘图代码,但是这本身还不够!主线程缓存 GDI 资源并定期对它们执行清理,这将影响您的TBitmap
. 因此,您还需要随时Lock/Unlock()
进行TBitmap.Canvas
绘图/渲染,以确保 VCL 不会在您背后剥夺其资源。
由于您的线程都在修改同一个位图,因此您需要序列化对该位图的所有访问。这意味着读取它的内容以及写入它。
当然,这假设多个线程绘制到共享位图是解决问题的正确方法。在不知道您的实际问题是什么的情况下,我无法对此发表评论。
更新
由于Remy's answer中描述的问题,您还必须Lock/Unlock
在绘制位图时使用。这应该是这个问题的公认答案。
当您的 TBitmap 像素发生更改时,使用监视器或信号量来控制您的线程!
您可以改用 TThread.Synchronize 方法吗?
根据 TThread 类的文档
以下是使用线程时需要注意的问题和建议:
跟踪太多线程会消耗 CPU 时间;建议的限制是单处理器系统上每个进程 16 个活动线程。
当多个线程更新相同的资源时,它们必须同步以避免冲突。
大多数访问对象和更新表单的方法只能在主线程中调用或使用同步对象,例如 TMultiReadExclusiveWriteSynchronizer。