问题
If many asynchronous threads draw in a global TBitmap, it will rise me an error? Should I create my code using a critical section? (From my surf on the internet I found that the TBitmap.Draw is not thread safe)
Another question: If many synchronous threads draw in a global TBitmap and a VCL Timer read asynchronously the content from the TBitmap will this rise me an error?
Thanks!
回答1:
Since your threads are all modifying the same bitmap, you need to serialize all access to that bitmap. That means reading its contents as well as writing to it.
Of course, this assumes that multiple threads drawing to a shared bitmap is the right solution to your problem. Without knowing what your actual problem is, I could not comment on that.
UPDATE
You must also use Lock/Unlock
when drawing to the bitmap because of the issue described in Remy's answer. Which should be the accepted answer to this question.
回答2:
Yes, you do need to protect the TBitmap
from concurrent access across multiple threads. A critical section is fine for serializing your drawing code, HOWEVER that is not enough by itself! The main thread caches GDI resources and performs cleanup on them periodically, which will affect your TBitmap
. As such, you will ALSO need to Lock/Unlock()
the TBitmap.Canvas
whenever drawing/rendering to ensure the VCL does not rip out its resources behind your back.
回答3:
Use monitors or semaphores to control your threads when they do changes in your TBitmap Pixels !
回答4:
Can you use the TThread.Synchronize method instead?
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Classes_TThread_Synchronize@TThread@TThreadMethod.html
According to the doco for TThread class
Following are issues and recommendations to be aware of when using threads:
Keeping track of too many threads consumes CPU time; the recommended limit is 16 active threads per process on single processor systems.
When multiple threads update the same resources, they must be synchronized to avoid conflicts.
Most methods that access an object and update a form must only be called from within the main thread or use a synchronization object such as TMultiReadExclusiveWriteSynchronizer.
来源:https://stackoverflow.com/questions/14171485/asynchronous-threads-drawing-in-bitmaps-delphi