It is a problem of synchronization. I made a simplification for my problem so I have a VCL Timer and a few threads. The threads are trying to write things in two bitmaps, and the timer is trying to draw the bitmaps into Images(TImage). Here is a modification of my code to be easier to understand(this paste code is very vague).
//------------------------------------------------------------------------------
Procedure TMyForm.Add(iX,iY,iNr:integer);
begin
EnterCriticalSection(csCriticalSection);
bmRed.Canvas.Lock;
bmBlue.Canvas.Lock;
//.... drawing etc...
bmRed.Canvas.TextOut(iX,iY,IntToStr(iNr));
bmBlue.Canvas.TextOut(iX,iY,IntToSTr(iNr));
bmRed.Canvas.Unlock;
bmBlue.Canvas.Unlock;
LeaveCriticalSection(csCriticalSection);
end;
//------------------------------------------------------------------------------
procedure TMyForm.tmTimer(...);
begin
EnterCriticalSection(csCriticalSection);
bmRed.Canvas.Lock;
bmBlue.Canvas.Lock;
//Drawing on bmRed and bmBlue
imBlue.Canvas.Draw(bmBlue);
imRed.Canvas.Draw(bmBlue);
bmRed.Canvas.Unlock;
bmBlue.Canvas.Unlock;
LeaveCriticalSection(csCriticalSection);
end;
//------------------------------------------------------------------------------
Procedure TMyThread.Execute();
begin
Randomize;
while not terminated do
begin
MyFormInstance.Add(Random(100),Random(100),Random(100));
Sleep(20);
end;
end;
initialization
InitializeCriticalSection(csCriticalSection);
finalization
DeleteCriticalSection(csCriticalSection);
Usually the threads gives me errors when entering in the critical section or after a few seconds the timer will no longer draw me anything.
Try adding exception handling to your code, and don't lock both bitmaps at the same time:
var
csCriticalSection: TRTLCriticalSection;
procedure TMyForm.Add(iX,iY,iNr:integer);
begin
EnterCriticalSection(csCriticalSection);
try
bmRed.Canvas.Lock;
try
bmRed.Canvas.TextOut(iX,iY,IntToStr(iNr));
finally
bmRed.Canvas.Unlock;
end;
bmBlue.Canvas.Lock;
try
bmBlue.Canvas.TextOut(iX,iY,IntToSTr(iNr));
finally
bmBlue.Canvas.Unlock;
end;
finally
LeaveCriticalSection(csCriticalSection);
end;
end;
procedure TMyForm.tmTimer(Sender: TObject);
begin
EnterCriticalSection(csCriticalSection);
try
bmRed.Canvas.Lock;
try
imRed.Canvas.Draw(bmBlue);
finally
bmRed.Canvas.Unlock;
end;
bmBlue.Canvas.Lock;
try
imBlue.Canvas.Draw(bmBlue);
finally
bmBlue.Canvas.Unlock;
end;
finally
LeaveCriticalSection(csCriticalSection);
end;
end;
procedure TMyThread.Execute;
begin
Randomize;
while not Terminated do
begin
MyFormInstance.Add(Random(100),Random(100),Random(100));
Sleep(20);
end;
end;
initialization
InitializeCriticalSection(csCriticalSection);
finalization
DeleteCriticalSection(csCriticalSection);
If that is still crashing/erroring, then you have a different bug in code you have not shown. Especially considering that you should never get an error entering/leaving a critical section, unless the critical section itself is corrupted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With