AGB  ·  Datenschutz  ·  Impressum  







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

TTask/ITask + Synchronze + OnDestroy

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

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.172 Beiträge
 
Delphi 11 Alexandria
 
#21

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 13:16
Ich weiß ja nicht, ob das für den realen Anwendungsfall passt, aber in solchen Fällen verwende ich dann ein Zwischenobjekt. Ich hab da mal was vorbereitet...
Danke dafür. Aber wenn ich den Task starte und das Fenster schließe, gibt es eine Zugriffsverletzung.Übersehe ich was?

Die Zugriffsverletzung sieht man aber nur im Debugger und nur wenn dias Unterbrechen bei Exceptions eingeschalten ist. Zur Laufzeit wird die Exception nicht angezeigt.

Gilt auch für TiGüs Vorschlag mit OnCloseQuery. Wahrscheinlich wird die Excpetion geworfen, wenn das ganze Exceptionhandling schon abgebaut ist.

Geändert von TigerLilly ( 8. Jan 2021 um 13:22 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 13:30
Nein, aber ich. Wenn das Form freigegeben wird, dann auch die Wrapper-Instanz - auch wenn die Task noch nicht fertig ist. In meinen Anwendungsfällen hält die Task indirekt selbst noch ein anderes Interface auf den Wrapper, aber dabei geht es auch um eine ganz andere Anforderung.

Multi-Threading bleibt halt schwierig...
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.172 Beiträge
 
Delphi 11 Alexandria
 
#23

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 13:38
Multi-Threading bleibt halt schwierig...
Ha! Und ich hab gedacht, ich bin unfähig. Danke trotzdem!
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 13:51
Neuer Versuch, der sich mehr an meinem (bislang jedenfalls funktionierenden) Code orientiert.
Ich vermute, das eigentliche Problem ist das Halten des ITask-Interfaces, was ich in meinem Code eigentlich nie mache.
Angehängte Dateien
Dateityp: zip TaskProjekt.zip (1,6 KB, 8x aufgerufen)
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
shebang

Registriert seit: 7. Feb 2020
96 Beiträge
 
Delphi 11 Alexandria
 
#25

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 14: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
10.934 Beiträge
 
Delphi 12 Athens
 
#26

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 15: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
96 Beiträge
 
Delphi 11 Alexandria
 
#27

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 16: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
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.172 Beiträge
 
Delphi 11 Alexandria
 
#28

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 8. Jan 2021, 16: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
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.172 Beiträge
 
Delphi 11 Alexandria
 
#29

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 11. Jan 2021, 08: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, 8x aufgerufen)
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.733 Beiträge
 
Delphi 6 Enterprise
 
#30

AW: TTask/ITask + Synchronze + OnDestroy

  Alt 11. Jan 2021, 09:06
Ich kenn mich mit Threads/Tasks nicht so aus, aber nur mal auf diesen Fall bezogen:

Könnte man den Thread nicht so bauen, dass er statt selber auf die GUI zuzugreifen eine Art Callback anbietet (den er ggf. synchronized abfackelt). Dann könnte man den Callback nämlich detachen, bevor man den Thread beendet. Denn warum soll der Thread noch die GUI updaten, wenn das Fenster eh gererade geschlossen werden soll.
Geht natürlich nur, wenn auf Threads von Außen nachträglich zugegriffen werden kann (wie gesagt, kenn mich damit nicht aus).
Ralph
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 02:38 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz