DELPHI XE5 up2, WIN 7 32BIT, Problem both in VCL and FMX.
Whatever I use such as
a Repaint, Invalidate, and all other paint actions are not thread-safe. You need to call synchronize to update the main thread:
Thanks, you are so kind and it works.
When I don't use Synchronize, I can easily close the application.
Only the final result needs to be set as value of the circulargauge. The result can be calculated inside the XXX procedure, the visual update needs to be synchronized. You need to replace FGaugeValue := Random() with your io operations code. You also have a memory leak because you do not free the thread and you set FreeOnTerminate to false. A better approach would be to check if the thread is terminated, and terminate the thread in the formclose.
Pieter Scheldeman2014-04-04 07:58:20
Hi i've same problem on a thread like this
While Not Terminated Do Begin
Try Try
//Synchronize(nil,
Queue(nil, // Queue è asincrono e 'refresha' meglio di Synchronize
Procedure
Begin
circulargaugeLTOUsc.Value:=....
circulargaugeLTOUsc.DisplayText := ...
circulargaugeTDS.Value:=...
circulargaugeTDS.DisplayText := ...
end;
Go fine until i do :
MonThread.Terminate();
MonThread.WaitFor();
FreeAndnil(MonThread);
but if i restart thread
MonThread:=TMonThread.Create(False);
animation freeze ... but circulargaugeTDS.DisplayText go fine show changed text. Thare is any way to refresh/repaint animation ?
Did you try the code snippet I posted?
i this same code . entire code here
formcreate
If Not Assigned(MonThread) Then Begin
MonThread:=TMonThread.Create(False);
{$IFDEF WIN32}
MonThread.Priority:=tpTimeCritical;
{$ENDIF}
End;
// -----------------------------------------------------------------------------
procedure TMonThread.Execute();
begin
While Not Terminated Do Begin
Try Try
//Synchronize(nil,
Queue(nil, // Queue è asincrono e 'refresha' meglio di Synchronize
Procedure
Begin
cgLTOUsc.Value:=StrToIntDef(frmTDPComPort.MonValues.Strings[lstLTO_USC_CORR],0);
// visualizza il valore in dettaglio
cgLTOUsc.DisplayText:=frmTDPComPort.MonValues.Strings[lstLTO_USC_CORR];
cgTDS.Value:=StrToIntDef(frmTDPComPort.MonValues.Strings[lstTDS_CORR],0);
// visualizza il valore in dettaglio
cgTDS.DisplayText:=frmTDPComPort.MonValues.Strings[lstTDS_CORR];
End);
End;
Except
On E:Exception Do Begin
If Assigned(MonThread)Then Begin
MonThread.Terminate();
MonThread.WaitFor();
FreeAndnil(MonThread);
End;
End;
End;
Finally
// fa qualcosa
End;
Sleep(100); // per evitare l'uso intensivo di CPU
End;
end;
// -----------------------------------------------------------------------------
Function TfrmTDPMon.CloseForm
Begin
If Assigned(MonThread)Then Begin
MonThread.Terminate();
MonThread.WaitFor();
FreeAndnil(MonThread);
End;
NOTE : circular objects not destroyed on CloseForm, form is always alive !
The code snippet you posted is NOT the same code as the code snippet in my post. Please try the code snippet in my post. I have retested this here and there are no issues with the code. If you are using another code snippet for threading and you want to access the circular gauge from within the thread, but you get issues when destroying, you are doing something wrong. Please revise the code.
Nothing i tried to call : Synchronize(nil, SyncCG); in main thread
and the procedure
Procedure TfrmTDPMon.SyncCG();
Begin
cgLTOUsc.Value:=StrToIntDef(frmTDPComPort.MonValues.Strings[lstLTO_USC_CORR],0);
// visualizza il valore in dettaglio
cgLTOUsc.DisplayText:=frmTDPComPort.MonValues.Strings[lstLTO_USC_CORR];
cgTDS.Value:=StrToIntDef(frmTDPComPort.MonValues.Strings[lstTDS_CORR],0);
// visualizza il valore in dettaglio
cgTDS.DisplayText:=frmTDPComPort.MonValues.Strings[lstTDS_CORR];
End;