Thema: Delphi Thread nicht terminiert?

Einzelnen Beitrag anzeigen

mcinternet

Registriert seit: 22. Apr 2010
Ort: Odenwald
193 Beiträge
 
Delphi 10.3 Rio
 
#1

Thread nicht terminiert?

  Alt 1. Feb 2013, 09:45
Delphi-Version: XE2
Hallo,

Umgebung: Rad Studio XE3 Update 2

Ich habe einen Thread (MThread), der während beim Click auf einen Button erzeugt wird. Mit Option freeonterminate=true
Ein Ereignis onThreadTerminate wird zugewiesen.
Nach Auslösen dieses Ereignisses wird einiges abgearbeitet - klappt auch alles soweit.
Nur ein merkwürdiges Phänomen tritt auf: Wenn ich irgendwann später MThread.terminated abfrage, so ist dieser immer noch aktiv. - Es stört nicht wirklich. Auch ein erneutes Erzeugen und Starten klappt problemlos.
Mache ich allerdings beim FormClose die Zeile: if assigned(MThread) then freeandnil(MThread) rein, knallt es.

(Stört Euch nicht an der Formvariable oder so - ich arbeite hier mit einem multiple Docked-Forms Konzept,
wo alle FRMs im Prinzip nur Muster sind und die Childforms dynamisch erzeugt werden - somit kann jede FRM
mit eindeutigem Namen versehen werden und ich nutze da auch verschiedene Muster)

Meine Problematik dreht sich nur um diesen MThread

Hier mal ein wenig Code:

Delphi-Quellcode:
type
  TFrmGMaps = class(TChildform)
    WebGMaps1: TWebGMaps;
    starttimer: TTimer;
    .
    .
    . weitere Definitionen ...
    private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;


  TMyThread = class(TThread)
     procedure execute; override;
  end;

 var

  threadaktiv : Boolean = False;
  MThread : TMyThread;
 
  // Form2 - Formvariable verworfen, wird bei Aufruf vergeben (Mutliple Forms)


implementation

{$R *.dfm}

uses main, childformverwaltung, System.StrUtils, UDM;

procedure TFrmGMaps.threadabschluss;
  var idx : integer;
  lat : string;
    lng : string;
    buwID : string;
    KName : string;
begin
  if not threadaktiv then begin
    threadtimer.Enabled := false;
    pan_warten.Visible := false;
    setstartmarker;
    for idx := 0 to Length(threadkname)-1 do begin
      lat := threadlat[idx];
      lng := threadlng[idx];
      KName := threadKName[idx];
      if ((lat<>'') and (lng<>'')) then WebGMaps1.Markers.Add(strtofloat(lat),strtofloat(lng),
                           ID+' '+KName,geticon(99, False),
                           True,True,True,False,false,idx);


    end;
    SetLength(threadlat,0);
    SetLength(threadlng,0);
    SetLength(threadkname,0);
    pan_gmapsteuerung.Visible := True;
  end;
end;

procedure TMyThread.Execute;
  var idx : integer;
   dynform : TFrmGMaps;

// GETCUMLIST_DIST_FROM ist ne ORacle Stored Proc

begin
 
    SetLength(threadlat,0);
    SetLength(threadlng,0);
    SetLength(threadkname,0);
    dynform := TFrmGMaps(Application.FindComponent(FrmMain.GmapThreadname));
    dynform.GETCUMLIST_DIST_FROM.execute;
    if dynform.GETCUMLIST_DIST_FROM.ParamByName('RESULT').Asinteger=DM.pkgCodes.VariableByName('INF_SUCCESS').AsInteger then
    begin
        idx := 0;
        dynform.JvGradientProgressBar1.Max := dynform.GETCUMLIST_DIST_FROM.RecordCount;
        SetLength(threadlat,dynform.GETCUMLIST_DIST_FROM.RecordCount);
        SetLength(threadlng,dynform.GETCUMLIST_DIST_FROM.RecordCount);
        SetLength(threadkname,dynform.GETCUMLIST_DIST_FROM.RecordCount);

        while (not dynform.GETCUMLIST_DIST_FROM.eof) do begin
          Synchronize(dynform.JvGradientProgressBar1.StepIt);
          inc(idx);
          if not ((dynform.GETCUMLIST_DIST_FROMCUM_DBLGEOLAT.AsString = dynform.gmaps_lat) // Um auszuschließen, das der Startmarker
             and ( dynform.GETCUMLIST_DIST_FROMCUM_DBLGEOLNG.AsString = dynform.gmaps_lng)) // überschrieben wird
          then begin
            SetLength(threadlat,idx);
            SetLength(threadlng,idx);
            SetLength(threadkname,idx);
            threadlat[idx-1] := dynform.GETCUMLIST_DIST_FROMCUM_DBLGEOLAT.AsString;
            threadlng[idx-1] := dynform.GETCUMLIST_DIST_FROMCUM_DBLGEOLNG.AsString;
            threadkname[idx-1] := dynform.GETCUMLIST_DIST_FROMCUM_STRNAME.AsString;
          end;
        dynform.GETCUMLIST_DIST_FROM.Next;
      end;
      dynform.GETCUMLIST_DIST_FROM.Close;
    end
    else
    begin
      //Fehler
    end;
end;

procedure TFrmGMaps.btn_querystartClick(Sender: TObject);
  var lat : string;
    lng : string;
    KName : string;
    idx : integer;
begin
  WebGMaps1.DeleteAllMapMarker;
  FrmMain.GmapThreadname := Self.Name;
  JvGradientProgressBar1.Position := 1;
  pan_warten.Left := Integer(Trunc((Self.Width - pan_warten.Width) / 2));
  pan_warten.Top := Integer(Trunc((Self.Height - pan_warten.Height) / 2));
  pan_warten.Visible := True;
  Application.ProcessMessages;
  MThread := TMyThread.Create(True);
  MThread.FreeOnTerminate := True;
  threadaktiv := true;
  MThread.OnTerminate := threadend;
  pan_gmapsteuerung.Visible := false;
  MThread.Resume;
end;

procedure TFrmGMaps.threadend(Sender: TObject);
begin
  threadaktiv := false;
  threadabschluss;
end;
irgendwo - irgendwann muss der Thread ja "zerstört" werden?

Gruss

MC
Jörg
  Mit Zitat antworten Zitat