Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Problem beim auswerten eines Threadergebnisses (https://www.delphipraxis.net/85437-problem-beim-auswerten-eines-threadergebnisses.html)

VizeTE 30. Jan 2007 20:07


Problem beim auswerten eines Threadergebnisses
 
Hallo zusammen,

hier mal meine Ausgangssituation:

Ich starte eine Internetabfrage um genau 1 Wert zu bekommen. Da das manchmal länger dauert habe ich mich dazu entschlossen diese Funktion in einen Thread auszulagern. Außerdem möchte ich nicht ewig auf die Antwort warten und breche den Thread im Zweifelsfall ab. Also etwa so:

1. Thread erstellen und mit Parameter versorgen
2. Zeit x auf Thread warten
3. Falls Thread fertig ist Ergebnis auswerten
4. Thread freigeben

Da ich in Punkt 3 das Ergebnis auswerten möchte habe ich "FreeOnTerminate" des Threads auf "false" gesetzt.

und nun das Problem

Wenn in Punkt 2 die Abfrage zu lange dauert wird der Thread ja abgebrochen. Punkt 3 wird übersprungen und ich gebe den Thread frei. Der Aufruf "Thread.Free" dauert in diesen Fall aber so lange bis der Thread die Abfrage beendet hat. Und genau das gefällt mir nicht.

Der Zeitfresser innerhalb des Threads ist die Methode "Connect" um eine Socket-Verbindung herzustellen. Dort sehe ich leider keine Möglichkeit die "Terminated"-Eigenschaft des Threads abzufragen und den Vorgang entsprechend zu beenden.

Meine erste Idee war es eine Möglichkeit zu finden "FreeOnTerminate" zu verwenden. Da ich aber in Punkt 3 auf den Thread zugreifen möchte wird das nicht funktionieren.
Eine Lösung wäre es vielleicht das Ergebnis via "OnTerminate"-Event in eine globale Variable zu schreiben und diese im Erfolgsfall auszulesen. Aber so richtig gefällt mir diese Lösung nicht.

Habt ihr eine Idee wie man das "ordentlich" lösen kann?


Danke,
Daniel

oki 30. Jan 2007 20:53

Re: Problem beim auswerten eines Threadergebnisses
 
Hi Daniel,

da kannst du imho wenig machen. Ich verstehe nur nicht, warum du den Thread unbedingt beenden willst. Er stört dich doch nicht. Genau dafür hast du das ganze doch in einen Thread ausgelagert.

Gruß oki

VizeTE 30. Jan 2007 21:23

Re: Problem beim auswerten eines Threadergebnisses
 
Ich muß ihn nicht unbedingt beenden. Aber da ich nicht "FreeOnTerminate" gesetzt habe muß ihn ja freigeben sofern ich mir nicht den Speicher zumüllen möchte.
Würde ich FreeOnTerminate jedoch setzen dann kann es ja passieren, dass der Thread schon weg ist wenn ich das Ergebnis abfragen möchte.

pathfinder78 30. Jan 2007 22:12

Re: Problem beim auswerten eines Threadergebnisses
 
Hallo,

ich wuerde FreeOnTerminate auf true lassen und als Parameter fuer den Thread eine Callback-Funktion (zB TNotifyEvent) uebergeben.
Die Execute Methode wird also in etwa so aussehen:
Delphi-Quellcode:
procedure Thread.Execute;
begin
  DoSomethingInTheWWW;
  if not Terminated then Synchronize(RequestFinished);
  Terminate;
end;

procedure Thread.RequestFinished;
begin
  if assigned(CallbackFunc) then CallbackFunc(self);
end;
In der CallbackFunktion kannst Du die Eigenschaften des Threads abfragen, da dieser ja dann noch existiert. Kommt vorher ein Timeout, rufst Du einfach Thread.Terminate auf.

VizeTE 31. Jan 2007 07:39

Re: Problem beim auswerten eines Threadergebnisses
 
Zitat:

Zitat von pathfinder78
In der CallbackFunktion kannst Du die Eigenschaften des Threads abfragen, da dieser ja dann noch existiert. Kommt vorher ein Timeout, rufst Du einfach Thread.Terminate auf.

Ich hoffe ich habs nicht falsch verstanden aber ich glaube das passt noch nicht richtig.
Ich möchte an der Stelle vom Code, an der ich den Thread loslaufen lasse, auch das Ergebnis wissen da sich das auf den nachfolgenden Code auswirkt. In der Callback-Funktion habe ich zwar das Ergebnis aber leider an einer Stelle an der ich nichts damit anfangen kann.
Die einzige Möglichkeit, die ich mit Verwendung einer Callback-Fkt. sehe, wäre das Ergebnis dann in eine globale Variable zu schreiben. Aber so richtig gefällt mir das nicht. (Bin kein Freund von globalen Variabeln :zwinker:)
Oder seh' ich den Wald vor Bäumen nicht?

pathfinder78 31. Jan 2007 10:06

Re: Problem beim auswerten eines Threadergebnisses
 
Nun, das ist doch aber der Sinn eines Threads. Zeitraubende Sachen werden in einem Thread ausgelagert und das Programm kann in dieser Zeit weiter arbeiten. In einem sequentiellen Ablauf, wie Du ihn beschreibst, macht es keinen Sinn, einen Thread zu starten, wenn Du gleich danach mit dem Ergebnis weiter arbeiten möchtest.

Schreib doch mal bitte, was genau in dem Programm gemacht werden soll.

VizeTE 31. Jan 2007 10:13

Re: Problem beim auswerten eines Threadergebnisses
 
Auf den ersten Blick macht es keinen Sinn da es sich tatsächlich um einen sequentiellen Ablauf handelt. Ich habe aber 2 Gründe dennoch einen Thread zu verwenden:

1. Wenn ich keinen Thread verwende bekommt der Hauptthread des Programms keine Rechenzeit bis die Aufgabe erledigt ist. Also werden die Fenster nicht neu gezeichnet und Windows meint auch das mein Programm nicht mehr reagiert.
2. Ohne Thread kann ich nicht nach Zeit x den Vorgang abbrechen.

VizeTE 1. Feb 2007 10:12

Re: Problem beim auswerten eines Threadergebnisses
 
Ich habs jetzt erstmal eine Notlösung gebaut.
Ich habe einen weiteren Thread geschrieben der mir den eigentlichen Thread freigibt. Das ist nicht schön, klar, aber es funktioniert erstaml.

Bin aber für weitere Anregungen offen! Denke nicht das ich der einzige mit dem Problem bin.

Luckie 1. Feb 2007 10:17

Re: Problem beim auswerten eines Threadergebnisses
 
Warum lässt du dich nicht über ein Ereignis vom Thread benachrichtigen, wenn er fertig ist udn gibst dem Ereignis die Ergebnisse als Parameter mit?

Kleines Demo.

Thread:
Delphi-Quellcode:
unit Unit2;

interface

uses
  Classes;

type
  TOnFinish = procedure(Sender: TObject; Value: Integer) of object;
  TMyThread = class(TThread)
  private
    FValue: Integer;
    FOnFinish: TOnFinish;
    procedure DoNotifyFinish;
  protected
    procedure Execute; override;
  public
    property OnFinish: TOnFinish read FOnFinish write FOnFinish;
  end;

implementation

{ TMyThread }

procedure TMyThread.DoNotifyFinish;
begin
  if Assigned(OnFinish) then
    OnFinish(Self, FValue);
end;

procedure TMyThread.Execute;
var
  i: Integer;
begin
  FValue := 0;
  for i := 0 to High(Integer) - 1 do
    Inc(FValue);
  Synchronize(DoNotifyFinish);
end;

end.
Hauptprogramm:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure OnFinish(Sender: TObject; Value: Integer);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  Unit2;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyThread: TMyThread;
begin
  MyThread := TMyThread.Create(True);
  MyThread.FreeOnTerminate := True;
  MyThread.OnFinish := OnFinish;
  MyThread.Resume;
end;

procedure TForm1.OnFinish(Sender: TObject; Value: Integer);
begin
  ShowMessage(IntToStr(Value));
end;

end.

VizeTE 1. Feb 2007 15:50

Re: Problem beim auswerten eines Threadergebnisses
 
Zitat:

Zitat von Luckie
Warum lässt du dich nicht über ein Ereignis vom Thread benachrichtigen, wenn er fertig ist udn gibst dem Ereignis die Ergebnisse als Parameter mit?

Ich hoff' ich versteh das nicht falsch aber ich denke der Vorschlag kam schon mal paar Postings weiter vorn.
Ich möchte an der Stelle, an der ich den Thread aufrufe, auch das Ergebnis haben da ich im folgenden Code entsprechend darauf reagieren möchte. Also ist das eher ein sequentieller Ablauf.
Dennoch möchte ich aber einen Thread verwenden (siehe paar Postings weiter vorn)


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:56 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