![]() |
Problem mit Task.Cancel
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,
ich habe ein Problem, einen Task in einer komplexen Umgebung sicher abzubrechen. In einem Testprojekt kann ich das Problem nicht nachstellen. Das reale Projekt (IDE-Experte) ist natürlich deutlich komplexer. In dem Task wird zunächst synchronisiert über die VCL ein Wert ermittelt, dann verarbeitet und wieder synchronisiert in die VCL ausgegeben. Im realen Projekt läuft die Datenverarbeitung in einem Interface-Objekt, dem der Task dazu für den evtl. Abbruch mit übergeben wird. Wenn ich dort ein Sleep(50+) mit einbaue funktioniert der Abbruch auch. Ohne Sleep wird die Exception von CheckCanceled nicht ausgelöst. Irgendwie scheint dann keine Zeit dafür zu sein. Aber ein andauerndes Sleep ist natürlich bei sehr häufigen Schleifendurchläufen auch nicht praktikabel. In dem Testprojekt habe ich die Berechnung jetzt noch nicht in ein eigenes Interface-Objekt ausgelagert. Ansonsten ist das Grundprinzip etwa nachgestellt. Das Testprojekt funktioniert allerdings mit und ohne Sleeps. Warum mein reales Projekt nicht so funktioniert konnte ich noch nicht klären. Wenn der Task nicht abgebrochen wird, dann mogelt sich der neue Task dazwischen, stellt die neuen Daten dar und dann werden die alten Daten weiter dargestellt. Kann jemand das Problem anhand dieser etwas unscharfen Beschreibung nachvollziehen?
Delphi-Quellcode:
procedure TForm1.ShowData;
const MaxY = 100; MaxX = 5; var S: String; begin if Assigned(TestTask) and (TestTask.Status = TTaskStatus.Running) then begin OutputDebugString(PWideChar('-> ' + 'cancel')); TestTask.Cancel; OutputDebugString(PWideChar('<- ' + 'cancel')); end; TestTask := TTask.Create( procedure var Y, X: Integer; A : Array[1..MaxY] of Array[1..MaxX] of String; begin try TThread.Synchronize(nil, procedure begin OutputDebugString(PWideChar('-> ' + 'snc GetData')); S := Edit1.Text; OutputDebugString(PWideChar('<- ' + 'snc GetData')); end); OutputDebugString(PWideChar('-> ' + 'calc')); // CALCULATION for Y := 1 to MaxY do begin for X := 1 to MaxX do begin A[Y, X] := S; TTask.CurrentTask.CheckCanceled(); OutputDebugString(PWideChar('...calc... ' + IntToStr(Y) + ', ' + IntToStr(X) + ' "' + S + '"')); // Sleep(100); end; end; OutputDebugString(PWideChar('<- ' + 'calc')); TThread.Synchronize(nil, procedure var Y, X: Integer; S : String; begin OutputDebugString(PWideChar('-> ' + 'snc ShowData')); Memo1.Clear; for Y := 1 to MaxY do begin for X := 1 to MaxX do begin S := A[Y, X]; OutputDebugString(PWideChar('...show... ' + IntToStr(Y) + ', ' + IntToStr(X) + ' "' + S + '"')); Memo1.Text := Memo1.Text + S + ' '; // Sleep(100); end; Memo1.Text := Memo1.Text + sLineBreak; end; OutputDebugString(PWideChar('<- ' + 'snc ShowData')); end); except on EOperationCancelled do Exit; end; end); TestTask.Start; end; |
AW: Problem mit Task.Cancel
Vielleicht eine dumme Antwort. (Wenn ja vergiß es einfach)
Unter umständen erstellst du irgendwo einen Deadlock schon mal mit TThread.Queue versucht an der stelle wo dein Problem auftritt? Zitat:
|
AW: Problem mit Task.Cancel
Ein Deadlock kann m.E. aktuell nicht vorliegen, da das Programm sich nicht aufhängt.
Lediglich der abzubrechende Task wird verspätet weiter bearbeitet. Eine Queue wird mir wohl auch nicht helfen, da sich diese vermutlich noch schlechter unterbrechen lässt. Danke aber dennoch. |
AW: Problem mit Task.Cancel
Ich habe einen offenbar funktionierenden und akzeptablen Workarround gefunden.
Aus dem Thread rufe ich MyProjekt.DoAllUnits auf und dort für jede Unit.DoAllLines... Nach jeder Unit führe ich jetzt ein Sleep(100) aus. Die Verzögerung hält sich somit in Grenzen und die hinfälligen Tasks wurden bisher immer bei mir abgebrochen. Als Workarround ist das erst mal ok. Wenn jemand noch einen besseren Tipp hat oder einen grundsätzlichen Fehler erkennt, wäre ich natürlich für eine Info dankbar. |
AW: Problem mit Task.Cancel
Hallo Stahli,
Du könntest evtl. die auf Delphi-Treff ![]()
Delphi-Quellcode:
ausprobieren. Vielleicht hilft es Dir.
KillTask
Gruß, Andreas |
AW: Problem mit Task.Cancel
Danke für den Tipp. Ich merke mir das mal vor, aber meine aktuelle Lösung scheint mir übersichtlicher zu sein.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:52 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