AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein TTask/ITask + Synchronze + OnDestroy
Thema durchsuchen
Ansicht
Themen-Optionen

TTask/ITask + Synchronze + OnDestroy

Ein Thema von TigerLilly · begonnen am 7. Jan 2021 · letzter Beitrag vom 11. Jan 2021
Antwort Antwort
shebang

Registriert seit: 7. Feb 2020
144 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 10:33
Dann wäre die Frage, ob ein Task für deine aktuelle Aufgabe geeignet ist. Wenn ich mir die verfügbaren Methoden von TTask so anschaue, dann sieht es für mich eher so aus, dass Tasks für kurze kleine Aufgaben gedacht sind, auf deren Erfüllung man wartet. Dein Beispiel enthält ja eine Schleife, die abgebrochen werden muss, es gibt kein reguläres Ende. Ich würde an dieser Stelle wohl eher einen Thread nehmen.

Geändert von shebang ( 8. Jan 2021 um 10:37 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von TigerLilly
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.241 Beiträge
 
Delphi 12 Athens
 
#2

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 12:03
Dann wäre die Frage, ob ein Task für deine aktuelle Aufgabe geeignet ist. Wenn ich mir die verfügbaren Methoden von TTask so anschaue, dann sieht es für mich eher so aus, dass Tasks für kurze kleine Aufgaben gedacht sind, auf deren Erfüllung man wartet. Dein Beispiel enthält ja eine Schleife, die abgebrochen werden muss, es gibt kein reguläres Ende. Ich würde an dieser Stelle wohl eher einen Thread nehmen.
Das erschließt sich mir nicht. TTask kapselt doch nur den Zugriff auf Threads. Die Endlos-Schleife samt Abbruch ist nur zu Testzwecken, ändert an der Aufgabenstellung nichts. In echt beendet der Task natürlich, wenn man ihn lässt.

Warum sollte hier ein Thread tauglicher sein als ein Task?
  Mit Zitat antworten Zitat
shebang

Registriert seit: 7. Feb 2020
144 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 13:24
Warum sollte hier ein Thread tauglicher sein als ein Task?
Einem Thread kann ich (über Terminate) mitteilen, dass er sich beenden soll und dann darauf warten, bis er sich selbst beendet hat. Bei einem Task scheint das nicht vorgesehen zu sein.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.643 Beiträge
 
Delphi 12 Athens
 
#4

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 14:28
Einem Thread kann ich (über Terminate) mitteilen, dass er sich beenden soll und dann darauf warten, bis er sich selbst beendet hat. Bei einem Task scheint das nicht vorgesehen zu sein.
Das geht mit ITask auch. Problematisch ist hier nur der Synchronize-Aufruf im Task-Thread, der mit dem Wait im Hauptthread zu einem Deadlock führt. Ohne geeignete Maßnahmen wäre das mit einem TThread auch so.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
shebang

Registriert seit: 7. Feb 2020
144 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 15:41
Problematisch ist hier nur der Synchronize-Aufruf im Task-Thread, der mit dem Wait im Hauptthread zu einem Deadlock führt. Ohne geeignete Maßnahmen wäre das mit einem TThread auch so.
Stimmt, der Task müsste selbst unterscheiden, ob er durch den Button oder über das Schließen der Form beendet wurde. Nur im ersten Fall ist eine weitere Synchronisation notwendig.
  Mit Zitat antworten Zitat
Benutzerbild von TigerLilly
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.241 Beiträge
 
Delphi 12 Athens
 
#6

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 15:57
Mit einem Timer geht es:

Code:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := true;
  if Assigned(fTask) then begin
    if fTask.Status = TTaskStatus.Running then
      fTask.Cancel;
    Timer1.Enabled := true;
    CanClose:=Button1.Enabled;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if Button1.Enabled then
    Close;
end;
Wenn das Formular geschlossen werden soll, wird der Task gecancelt. Ist der Task aber nocht fertig beendet, wird das Schließen unterbunden + statt dessen ein Timer gestartet, der 1x/sec nachschaut, ob der Task jetzt endlich fertig ist. Wenn ja, wird das Formular geschlossen.

Besser?
  Mit Zitat antworten Zitat
Benutzerbild von TigerLilly
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.241 Beiträge
 
Delphi 12 Athens
 
#7

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 11. Jan 2021, 07:46
Uwe hat mich auf die Idee eines Wrappers gebracht, in den man diesen Overhead verpacken kann. Dann schaut das Beenden - mit Warten bis der Task fertig abgebrochen ist, so aus:
Code:
procedure TvTaskWrapper.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := aTaskWrapper.CancelTaskWithWait;
end;
Und das tut nicht viel mehr, als zu schauen, ob der Task fertig ist, wenn nicht wird ein Timer gestertet und das Schließen unterbunden. Der Timmer versucht dann immer wieder, das Close aufzurufen + das Spiel beginnt von vorn:
Code:
function TTaskWrapper.CancelTaskWithWait: TCloseAction;
begin
  if isActive then begin
    CancelTask;
    fTimer.Enabled := true;
    Result := TCloseAction.caNone;
  end else begin
    Result := TCloseAction.caFree;
  end;
end;
Auch das Syncen mit dem UI-Thread und einen Status, damit man weiß, wann der Thread fertig ist, kann man reinpacken:
Code:
type
  TTaskWrapper = class
  private
    fTimer: TTimer;
    fTask: ITask;
    fForm: Tform;
    fisActive: Boolean;
    procedure fOnTimer(Sender: TObject);
    function ShouldStop: Boolean;
  public
    constructor create(aForm: Tform; aProc: TProc);
    destructor Destroy;
    procedure DoSynchronized(aProc: TProc);
    procedure CancelTask;
    function CancelTaskWithWait: TCloseAction;
    property isActive: Boolean read FisActive write FisActive;
  end;
Demo attached. Ach ja: Das ist ein proof-of-concept + ist offen für Verbesserung.
Angehängte Dateien
Dateityp: zip TaskWrapper.zip (2,0 KB, 9x aufgerufen)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:26 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz