AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Prüfen ob Thread noch läuft

Ein Thema von Schwedenbitter · begonnen am 24. Jan 2007 · letzter Beitrag vom 9. Feb 2009
Antwort Antwort
Seite 1 von 3  1 23      
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#1

Prüfen ob Thread noch läuft

  Alt 24. Jan 2007, 15:44
Hallo,

ich möchte mittels meines Programms Dateien verschieben. Da es viele Dateien sein können und ich das ganze über einen langsamen VPN-Tunnel machen muss, würde das Programm ewig still stehen. Aus diesem Grunde habe ich die Prozeduren für das Kopieren und Löschen der Dateien in einen Thread gepackt. So weit - so gut. Allerdings habe ich immer noch folgende Probleme:

Da das Verschieben im Thread stattfindet, könnte es passieren, dass der Benutzer das Fenster schließt und das Programm damit beendet. Dann bestünde aber die Gefahr, dass offene Dateien zurückblieben, was auf die Dauer gesehen sehr unschön wäre. Die Eigenschaft Terminated gibt mir leider nur zurück, ob der Thread beendet werden soll. Aber nicht ob und wann er es nach dem Abarbeiten seiner Aufgaben selbst macht. Andere brauchbare Eigenschaften konnte ich in der Hilfe nicht finden. Ich habe mir bisher über eine globale Variable geholfen. Diese wird vor Ausführung des Thread auf True gesetzt und im Thread nach dem letzten Befehl erst auf False.

Gibt es bessere Methoden und falls ja, welche?

Außerdem bekomme ich beim Beenden des Programms hin und wieder die Fehlermeldung Exception der Klasse EOSError aufgetreten / Systemfehler. Code: 1400 Ungültiges Fensterhandle.

Was hat das zu bedeuten?

Schließlich habe ich trotz Verwendung eines Thread immer noch nicht in den Griff bekommen, dass sich das Fenster flüssiger bewegen lässt. Mir ist klar, dass BlockRead und BlockWrite bewusst größere Datenmengen verarbeiten und bei einem schlechten Durchsatz Verzögerungen hervorrufen. Aber ich dachte, dass das bei Ausführung im Thread im Hintergrund liefe und man in Ruhe weiterarbeiten kann.

Was mache ich falsch?

Falls Bedarf besteht, kann ich auch Quellcode reinsezten. Ich bitte dann aber um Erklärung was gebraucht wird; 400 Zeilen sind zuviel.

[edit=SirThornberry]Titel korrigiert - Mfg, SirThornberry[/edit]
Alex Winzer
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Prüfen ob Thread noch läuft

  Alt 24. Jan 2007, 16:05
z.B. kann man das mit Klassenmethoden machen. Da kannst du jederzeit abfragen, ob noch ein Thread läuft, auch wenn das Objekt selber nicht mehr existiert:
Delphi-Quellcode:
type
  tmythread = class(TThread)
  private
    { Private-Deklarationen }
  protected
    procedure Execute; override;
  public
    class function isrunning:boolean;
  end;

implementation

var running:integer=0;
{}

procedure tmythread.Execute;
begin
  inc(running);
  { Thread-Code hier einfügen }
  dec(running);
end;

class function tmythread.isrunning:boolean;
begin
  result:=running>0;
end;
inc und dec kann man auch in den constructor/destructor schreiben.


Dein Fehler kennn ich nicht. Aber ich würde vermuten, dass der Thread noch nicht beendet ist, wenn du den Hauptthread schließt. Fragst du in execute regelmäßig die Variable terminated ab?
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: Prüfen ob Thread noch läuft

  Alt 24. Jan 2007, 16:14
Hallo Schwedenbitter,

Auszug aus dem Delphi-Thread-Demo:
Delphi-Quellcode:
procedure TThreadSortForm.StartBtnClick(Sender: TObject);
begin
  RandomizeArrays;
  ThreadsRunning := 3;
  with TBubbleSort.Create(BubbleSortBox, BubbleSortArray) do
    OnTerminate := ThreadDone;
  with TSelectionSort.Create(SelectionSortBox, SelectionSortArray) do
    OnTerminate := ThreadDone;
  with TQuickSort.Create(QuickSortBox, QuickSortArray) do
    OnTerminate := ThreadDone;
  StartBtn.Enabled := False;
end;

procedure TThreadSortForm.ThreadDone(Sender: TObject);
begin
  Dec(ThreadsRunning);
  if ThreadsRunning = 0 then
  begin
    StartBtn.Enabled := True;
    ArraysRandom := False;
  end;
end;
Stahli
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#4

Re: Prüfen ob Thread noch läuft

  Alt 24. Jan 2007, 17:25
Wenn ein Thread seine Aufgaben nicht ordnungsgemäss oder vollständig erfüllen konnte,
sollte man im Thread das Property ReturnValue auf einen Fehlercode setzen.
Am besten speichert man alle Threads, die man erzeugt hat, in einer Liste (TObjectList).
Im Event OnTerminate sorgt man dann dafür, dass der Thread aus der Liste entfernt wird.

Durch das Speichern aller Threads in der Liste hat man die volle Kontrolle und kann auch jederzeit die Anzahl der laufenden Threads ermitteln.
Andreas
  Mit Zitat antworten Zitat
Pfoto

Registriert seit: 26. Aug 2005
Ort: Daun
541 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Prüfen ob Thread noch läuft

  Alt 24. Jan 2007, 17:51
Hi!

Wenn das Abarbeiten der Aufgabe im Thread das Hauptfenster immer noch teilweise zum Stehen bringt
oder etwas ruckelt, dann deutet das noch auf eine nicht korrekte Lösung hin.
Ist jetzt schwer etwas von hier zu vermuten...


Aber noch zum Beenden:

Probier das hier im OnCloseQuery Ereignis des Forms:
Delphi-Quellcode:
with myThread do
begin
  Terminate;
  WaitFor;
  Free;
end;
FreeOnTerminate muss aber dann anfangs False sein.


Gruß
Pfoto
Jürgen Höfs
  Mit Zitat antworten Zitat
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Prüfen ob Thread noch läuft

  Alt 24. Jan 2007, 21:58
Herzlichen Dank für die schnellen Antworten. Ich habe es jetzt mit dem Quellcode von sirius gemacht. Das funktioniert prima. Auf eine Liste verzichte ich, weil es nur einen Thread gibt. Werde mir das aber merken, falls ich mal was schwierigeres programmieren muss.

@Pfoto Ich will nicht behaupten, dass mein Code fehlerfrei ist. Schließlich bin ich absoluter Gelegenheitsprogrammierer und nehme Delphi nur, um mir die Arbeit auf Arbeit etwas einfacher zu machen. Allerdings habe ich Quelle und Ziel auf dieselbe Festplatte gelegt und eine 150 MB Datei für Versuchszwecke genommen. Fenster ruckelt kein bisschen. Liegt also wirklich am VPN. Was will man auch von 250 KBit/s upload bei DSL erwarten.
Den Quellcode habe ich probiert. Bei mir dauert es damit ca. 4 Sekunden, bis das Programm beendet ist, nachdem ich auf das Kreuz geklickt habe.

Ich habe jetzt auch die Quelle für die Exception gefunden. Allerdings weiß ich nicht, woran es wirklich liegt.
Ich hatte nach entsprechendem Quelltext aus dem Forum versucht, eine ProgressBar in eine Statusbar zu integrieren. Ich hatte zuerst die ProgressBar völlig gelöscht. Und siehe da, der Fehler trat nicht mehr auf. Anschließend ließ ich die ProgressBar drin. Allerdings separat und nicht mehr integiert. Der Fehler trat wieder auf. Jetzt ist sie ganz raus. Aber der Benutzer sieht jetzt leider nicht mehr, wie weit das Programm fortgeschritten ist. Schade.
Alex Winzer
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#7

Re: Prüfen ob Thread noch läuft

  Alt 24. Jan 2007, 22:13
Was ist denn bei dem Code von sirius, wenn man mehrere Threads startet? Dann klappt das nämlich nicht. Die Idee ist zwar ganz ok, aber eben nicht vollständig richtig.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: Prüfen ob Thread noch läuft

  Alt 25. Jan 2007, 08:26
Zitat von alzaimar:
Was ist denn bei dem Code von sirius, wenn man mehrere Threads startet? Dann klappt das nämlich nicht. Die Idee ist zwar ganz ok, aber eben nicht vollständig richtig.
Jep, richtig, war ja auch nur so ein Ansatz.
Ich kann ja nicht immer Ansätze liefern, die komplett auf alle Probleme passen
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: Prüfen ob Thread noch läuft

  Alt 25. Jan 2007, 08:32
Zitat von alzaimar:
Was ist denn bei dem Code von sirius, wenn man mehrere Threads startet?
Eigentlich sollte es auch mit mehreren Threads funktionieren. Wird einer gestartet, dann erhöht sich der Zähler um 1. Wird einer beendet, dann reduziert er sich wieder um 1. Macht im Ergebnis Null, wenn alle beendet sind. Dabei spielt es keine Rolle, in welcher zeitlichen Abfolge die Threads ablaufen.
Man muss meiner Meinung nach nur dafür sorgen, dass man bei den Terminated-Abfragen vor dem Beenden mitten im Thread auch eins runter zählt. Dann sollte es doch stimmen, oder?
Delphi-Quellcode:
procedure tmythread.Execute;
begin
  inc(running);
  { Thread-Code hier einfügen }
  if terminated then
  begin
    dec(running);
    exit;
  end;
  { Thread-Code-Ende }
  dec(running);
end;
Denn die Funktion IsRunning prüft nur, ob der Zähler Null ist.
Alex Winzer
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: Prüfen ob Thread noch läuft

  Alt 25. Jan 2007, 08:38
Zitat von Schwedenbitter:
Zitat von alzaimar:
Was ist denn bei dem Code von sirius, wenn man mehrere Threads startet?
Eigentlich sollte es auch mit mehreren Threads funktionieren. Wird einer gestartet, dann erhöht sich der Zähler um 1. Wird einer beendet, dann reduziert er sich wieder um 1. Macht im Ergebnis Null, wenn alle beendet sind. Dabei spielt es keine Rolle, in welcher zeitlichen Abfolge die Threads ablaufen.
Man muss meiner Meinung nach nur dafür sorgen, dass man bei den Terminated-Abfragen vor dem Beenden mitten im Thread auch eins runter zählt. Dann sollte es doch stimmen, oder?

Denn die Funktion IsRunning prüft nur, ob der Zähler Null ist.
Ja das ist auch wieder richtig. Ich meinte ja: Je nach Anwendungsfall.
Ein Problem kriegt man z.B. mit dieser Variante, wenn deine Threads mit "freeonterminate=TRUE" laufen. Dann werden sie automatisch aus dem Speicher entfernt:
Wenn z.b ThreadInstanz1 bereits fertig ist und ThreadsInstanz2 noch läuft dann gibt dir "isRunning" True zurück und wenn du dann ThreadInstanz1.waitfor aufrufst, kriegts du eine Zugriffsverletzung.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 09:08 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