Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - GIF friert bei Thread ein


momo_9376781 - Mo 17.12.12 09:45
Titel: GIF friert bei Thread ein
Hallo zusammen,

ich will den Quelltext einer Website auslesen. Dazu verwende ich die TIdHTTP Komponente.
Da das Auslesen mehrere Minuten dauern kann habe ich diese Funktion zum Auslesen des Quelltextes in ein
Thread geschrieben.
Um eine Rückmeldung zu haben sollte eine GIF Anmitation starten, wenn ich den Thread starte.
Dieses GIF friert aber trotz des Threads ein. Was mach ich falsch??
Hier noch ein wenig Quellcode:

Code im Thread

Delphi-Quelltext
1:
2:
3:
...
res := IdHTTP1.Get('***************');
....


Aufruf des Threads

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
...
Image1.Enabled := True;
Image1.Visible := True;
Site := Thread_Read.Create;
res :=  Thread_Read.Start('Parameter1''Parameter2');
...


Nersgatt - Mo 17.12.12 09:52

Hallo und willkommen in der EE! :welcome:

Du rufst .Start von der Klasse (Thread_Read) auf, nicht von Deiner Klasseninstanz (site).
Du solltest Deine eigenen Klassen immer mit T beginnen lassen. Also ein besserer Name wäre somit TThread_Read. Das ist in der Delphiwelt allgemein Usus.


momo_9376781 - Mo 17.12.12 09:59

Hi,
Danke für die schnelle Antwort.


Delphi-Quelltext
1:
2:
  Site := TThread_Read.Create;
  res :=  Site.Start('Parameter1''Parameter2');


Hab das jetzt so abgeändert. Das Problem bleibt aber immer noch gleich.. :-(
Oder hab ich was falsch verstanden?

Grüßle


Nersgatt - Mo 17.12.12 10:01

Poste mal bitte Deine komplette Threadklasse. Ich hab das Gefühl, dass Du die Startmethode nicht richtig überladen hast.


momo_9376781 - Mo 17.12.12 10:05


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
unit UT_Site;

interface

uses
  System.Classes;

type
  TThread_Read = class(TThread)
  private
    { Private-Deklarationen }
  protected
    procedure Execute; override;
  public
    function Start(Parameter1, Parameter2 : String) : Stringvirtual;
  end;

implementation

{ TThread_Read }

procedure TThread_Read.Execute;
begin
  { Thread-Code hier einfügen }
end;

function TThread_Read.Start(Parameter1, Parameter2 : String) : String;
var
res : String;
begin

  try
    res := IdHTTP1.Get(Parameter1);
  finally
    Result := res;
  end;
end;

end.


Nersgatt - Mo 17.12.12 10:19

Ok, sowas hab ich mir gedacht. Du hast eine Function eingeführt, die Start heißt. Du musst aber die procedure .Execute überschreiben (diese wird von .Start aufgerufen). Änder das mal so ab:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
unit UT_Site;

interface

uses
  System.Classes;

type
  TThread_Read = class(TThread)
  private
    FParameter2: String;
    FParameter1: String;
    procedure SetParameter1(const Value: String);
    procedure SetParameter2(const Value: String);
    { Private-Deklarationen }
  protected
    procedure Execute; override;
  public
    property Parameter1 : String read FParameter1 write SetParameter1;
    property Parameter2 : String read FParameter2 write SetParameter2;
  end;

implementation

{ TThread_Read }


{ TThread_Read }

procedure TThread_Read.Execute;
begin
  inherited;

  IdHTTP1.Get(Parameter1);

end;

procedure TThread_Read.SetParameter1(const Value: String);
begin
  FParameter1 := Value;
end;

procedure TThread_Read.SetParameter2(const Value: String);
begin
  FParameter2 := Value;
end;

end.


der Aufruf sieht dann so aus:

Delphi-Quelltext
1:
2:
3:
site.Parameter1 := 'test';
site.Parameter2 := 'test';
site.start;


So wie Du es gemacht hast, wird .Start im Mainthread ausgeführt.


momo_9376781 - Mo 17.12.12 10:28

Hmm ok
Hab das jetzt so abgeändert. Nun kommt eine Fehlermeldung:

... 'Start kann für eine laufenden oder unterbrochenen Thread nicht aufgerufen werden' ...

:-(


momo_9376781 - Mo 17.12.12 10:30

AAh ok hatte noich
Site := TThread_Read.Create;
stehen.
Aber wenn ich das raus nehme kommt eine access violation Fehlermeldung ....


Nersgatt - Mo 17.12.12 10:33

Der Aufruf muss drin bleiben, aber so aussehen:

Delphi-Quelltext
1:
Site := TThread_Read.Create(false);                    


So wird der Thread pausiert erstellt. Sonst wird direkt beim erstellen der Instanz der Thread gestartet (also sofort Start -> Execute aufgerufen). Dann hast Du aber keine Chance mehr, die Parameter zu setzen. Also pausiert starten (siehe oben).


momo_9376781 - Mo 17.12.12 10:37

Sorry aber ich glaub ich checks nicht :-(
Hab den Aufruf jetzt so:


Delphi-Quelltext
1:
2:
3:
4:
  Site:= TThread_Read.Create(false);          
  Site.Parameter1 := 'test1';
  Site.Parameter2 := 'test2';
  Site.Start;


Die Fehlermeldung (... 'Start kann für eine laufenden oder unterbrochenen Thread nicht aufgerufen werden' ... ) kommt aber noch


haentschman - Mo 17.12.12 10:43

user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
Der Aufruf muss drin bleiben, aber so aussehen:

Delphi-Quelltext
1:
Site := TThread_Read.Create(false);                    


So wird der Thread pausiert erstellt. Sonst wird direkt beim erstellen der Instanz der Thread gestartet (also sofort Start -> Execute aufgerufen). Dann hast Du aber keine Chance mehr, die Parameter zu setzen. Also pausiert starten (siehe oben).


...ist genau umgekehrt. Der Parameter beim Create heißt "Suspended". Wenn du den Thread suspended, also nicht laufend, erstellen möchtest ist der Parameter "True". Dann greift auch das "Start".


Nersgatt - Mo 17.12.12 10:44

Sorry, mein Fehler. Richtig ist Site:= TThread_Read.Create(True);


haentschman - Mo 17.12.12 10:47

Kein Problem... :P Da war wohl der Koffeinpegel nicht ausreichend genug.... 8)


momo_9376781 - Mo 17.12.12 10:47

Perfekt :-)

Vielen Vielen Dank!