canvas.handle can be temporary set to 0 by vcl in a bloc between canvas.lock and canvas.unlock so it can be temporary invalid if a thread interrupt the code without calling canvas.lock In multl threaded application.. This is what happened in procedure TCustomPaintBox32.Flush (may be otherwhere)
canvas.lock must be placed before testing canvas.handle (if canvas.handle <> 0)...
I have tested the patch in my muultithreaded application and it work
TCustomPaintBox32.Flush correction
same bug in procedure TCustomPaintBox32.Flush(const SrcRect: TRect);