Hallo und guten Abend,
ich habe folgendes Programmkonstrukt:
1. Hauptthread (der die
VCL bedient)
2. Arbeiterthread, der bestimmte Werte über eine Schnittstelle holt und diese über Synchronize an den Hauptthread übergibt.
Ich habe nun folgendes Problem, der 2. Thread soll ja weitesgehend selbsständig im Hintergrund laufen, und sich immer dann melden, wenn er neue Werte hat...
Das klappt auch, mein Problem ist, dass ich ihn synchronisieren muss mit dem Hauptthread, und zwar genau dann, wenn ich vom Hauptthread auch auf die Schnittstelle zugreifen will..
aThread.Suspend;
Kommt nicht Frage, da ich nie genau weiß in welchem Zustand mein Schnittstellenobjekt gerade ist(könnte ja sein, dass er gerade gesendet hat)..
Ich muss also den Thread in einem definierten Zustand stoppen können, habe das
zurzeit folgendermaßen gelöst:
Delphi-Quellcode:
procedure TCyclicData.Execute;
var
I: Integer;
merkeTimeOutProz: procedure (Sender:TObject) of object;
begin
while Not(Terminated) do
begin
// Synchronize(fSTK.Kommunikation.Sch);
merkeTimeOutProz:=fSTK.Kommunikation.OnTimeOut;
fSTK.Kommunikation.OnTimeOut:=Self.ShowTimeOut;
// if MaskeAnalogAusgangAktiv then exit;
feinDataset.aktuellerFlow:=fSTK.aktFlow;
feinDataset.Summation:=fSTK.Summation;
feinDataset.Status:=fSTK.Status;
feinDataset.Counts:=fSTK.Kommunikation.Counts;
// feinDataset.Dezimalstelle:=fSTK.DezimalStelle;
// =====KALIBRIERUNG======//
if (MaskeKalibrierungAktiv) then
begin
if (fSTK.isMulti) then
begin
for I := 1 to length(fChannels) do
begin
// Laufe jeden verfügbaren Kanal durch
if fChannels[i] then
begin
fSTK.KanalWechsel:=I;
fDataSetKalib[I].KanalNr:=I;
fDataSetKalib[I].KanalAktiv:=true;
fDataSetKalib[I].DeltaTempCorr:=fSTK.DeltaTempCorr;
fDataSetKalib[I].T2:=fSTK.T2;
fDataSetKalib[I].DeltaTRoh:=fSTK.DeltaTRoh;
end; // of if fChannels[i] then
end; // of for I := 0 to length(fChannels) - 1 do
end; // of if fSTK.isMulti then
Synchronize(SyncKanalData);
feinDataset.T2:=fSTK.T2;
feinDataset.DeltaTRoh:=fSTK.DeltaTRoh;
end; // of if MaskeKalibrierungAktiv then
// =====SONSTIGES======//
if (MaskeSonstigesAktiv) then
begin
feinDataset.aktuellerFlow:=fSTK.aktFlow;
feinDataset.aktFlowSkaliert:=fSTK.aktFlowSkaliert;
feinDataset.DeltaTRoh:=fSTK.DeltaTRoh;
end; // of if MaskeSonstigesAktiv then
if (MaskeDataloggingAktiv) then
begin
// Lese Anzahl DS
feinDataset.DataSetCounts:=fSTK.DataSetCounts;
fSTK.DataLogConfig;
end; // of if (MaskeDataloggingAktiv) then
//-----------------------------------> WICHTIGER BEREICH
if (fShouldStopp) then
begin
fSyncObj.Acquire;
fIsStopped:=true;
fSyncObj.Release;
while fShouldStopp do
begin
Sleep(10);
if Self.Terminated then exit;
end;
//-----------------------------------> WICHTIGER BEREICH
fSyncObj.Acquire;
isStopped:=false;
fSyncObj.Release;
end
else
begin
fSyncObj.Acquire;
isStopped:=false;
fSyncObj.Release;
end; // of if (fShouldStopp) then
// if MaskeAnalogAusgangAktiv then exit;
fSTK.Kommunikation.OnTimeOut:=merkeTimeOutProz;
Synchronize(Self.SyncOnNewData);
Sleep(100);
end;
end;
Im Hauptthread setzte ich also die Variable fshouldstopp und warte dann bis der Thread dann die Variable isStopped gesetzt hat, um zuwissen, dass er gestoppt hat.
Das passiert folgendermaßen (sollte besser mit Signalen arbeiten, oder??)
Delphi-Quellcode:
(*******************************************************************************
Prozedur zum stoppen des Hintergrund Tasks
*******************************************************************************)
procedure TFrmMain.StoppBackgroundTask;
begin
if Assigned(aCyclicDataThread) then
begin
aCyclicDataThread.PleaseStopp;
while (Not aCyclicDataThread.isStopped) do
begin
if Not(einSTK.Kommunikation.Schnittstelle.isConnected) then exit;
if(Application.Terminated) then exit;
end; // of while (Not aCyclicDataThread.isStopped) do
end; // of if Assigned(aCyclicDataThread) then
end;// of procedure TFrmMain.StoppBackgroundTask;
////////////////////////////////////////////////////////////////////////////////
Könnt ihr mir helfen, wie ich das besser lösen kann??
Danke euch