Autor Beitrag
Hendi48
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 271



BeitragVerfasst: Do 23.08.07 18:19 
Hi,
ich habe einen DownloadThread:
ausblenden volle Höhe 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:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
unit Thread2;

 
interface  

 
uses Windows, SysUtils, Classes, IdHTTP, IdComponent, SyncObjs;  

 
type  
  TThreadWorkEvent = procedure(Sender: TThread; AWorkMode: TWorkMode; const AWorkCount: Integer)  
   of object;  
  TWorkBeginEvent = procedure(Sender: TObject; AWorkMode: TWorkMode;  
   const AWorkCountMax: Integer) of object;  

type  
  DownloadThread = class(TThread)
  private  
    FIdHTTP: TIdHTTP;  
    FWorkEvent: TThreadWorkEvent;  
    FURL: String;  
    FFileName: String;  
    FWorkCountMax: Integer;  
    procedure InternalOnWork(ASender: TObject; AWorkMode: TWorkMode;
      AWorkCount: Integer);
    procedure InternalOnWorkBegin(ASender: TObject; AWorkMode: TWorkMode;
      AWorkCountMax: Integer);
  protected
    procedure Execute; override;  
  public
    constructor Create;  
    destructor Destroy; override;  
    property URL: String read FURL write FURL;  
    property FileName: String read FFileName write FFileName;  
    property WorkCountMax: Integer read FWorkCountMax;  
    property OnWork: TThreadWorkEvent read FWorkEvent write FWorkEvent;  
  end;  

 
implementation  

constructor DownloadThread.Create;
begin
  inherited Create(True);  
  FIdHTTP := TIdHTTP.Create(nil);
  FIdHTTP.OnWork := InternalOnWork;
  FIdHTTP.OnWorkBegin := InternalOnWorkBegin;
end;  

destructor DownloadThread.Destroy;
begin
  FIdHTTP.Free;  
  inherited;
end;  

procedure DownloadThread.Execute;
var  
  Handle: THandle;  
  FS: TFileStream;  
begin  
  Handle := FileCreate(FileName);
  if Handle <> INVALID_HANDLE_VALUE then  
  begin  
    FS := TFileStream.Create(Handle);  
    try  
      FIdHTTP.Get(FURL, FS);  
    finally  
      FS.Free;  
    end;  
  end;
end;  

procedure DownloadThread.InternalOnWork(ASender: TObject; AWorkMode: TWorkMode;
      AWorkCount: Integer);
begin
  if Assigned(FWorkEvent) then
    FWorkEvent(Self, AWorkMode, AWorkCount);
end;  

procedure DownloadThread.InternalOnWorkBegin(ASender: TObject; AWorkMode: TWorkMode;
      AWorkCountMax: Integer);
begin  
  FWorkCountMax := AWorkCountMax;
end;  

end.

Der funktioniert auch eigentlich, nur manchmal stoppt es einfach mitten im Download.

Der Aufruf ist so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  Thread2 := DownloadThread.Create;
  with Thread2 do
  begin
    FreeOnTerminate := True;
    OnWork := Self.OnWork;
    URL := 'http://battlefield-basis.de/bf2maps/Kursk.zip';
    FileName := 'test.zip';
    Resume;
  end;

(Thread2: DownloadThread; in private deklariert)
Brauch ich da vielleicht noch ein Synchronize oder so? (sry kenn mich mit Threads nicht wirklich aus)

Edit: aja ich hab noch OnWork (von MainForm) vergessen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TMainForm.OnWork(Sender: TThread; AWorkMode: TWorkMode; const AWorkCount: Integer);
const
  S_MSG = '%d Bytes von %d Bytes gedownloadet.';
begin
  if Sender = Thread2 then
    Label1.Caption := Format(S_MSG, [AWorkCount, (Sender as DownloadThread).WorkCountMax]);
    Progress2.Max := (Sender as DownloadThread).WorkCountMax;
    Progress2.Position := AWorkCount
end;
arj
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 378

Win XP/Vista, Debian, (K)Ubuntu
Delphi 5 Prof, Delphi 7 Prof, C# (#Develop, VS 2005), Java (Eclipse), C++, QT, PHP, Python
BeitragVerfasst: Fr 24.08.07 08:48 
Da du GUI-Darstellungen in deinem Thread änderst MUSST du die Methode Synchronize benutzen,
wie du schon richtig erkannt hast.

Versuch also mal, alles was an der GUI rumschraubt in ne Methode UpdateGUI zu schreiben
und diese dann mit Synchronize(UpdateGUI); aufzurufen.
Hendi48 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 271



BeitragVerfasst: Fr 24.08.07 13:45 
Aber eigentlich wird doch nur in der MainForm OnWork was am GUI geändert. Soll ich das trotzdem Synchrnisieren?
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 24.08.07 13:54 
Moin!

user profile iconHendi48 hat folgendes geschrieben:
Aber eigentlich wird doch nur in der MainForm OnWork was am GUI geändert. Soll ich das trotzdem Synchrnisieren?

Genau das ist der Grund, warum du sychronisieren sollst! :mahn:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Hendi48 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 271



BeitragVerfasst: Fr 24.08.07 14:17 
ok, ich hab Mainform.Onwork jetz so umgeändert:
ausblenden Delphi-Quelltext
1:
2:
  if Sender = Thread2 then
    Synchronize(UpdateGUI);

Ich kuck mal ob es jetzt geht.. :)

Edit: Er hat Fehler beim Compilen: Bei dem Synchronize() meint er Operator oder Semikolon fehlt und woher soll die Update GUI Procedure eigentlich wissen was AWorkCount is und so?
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Fr 24.08.07 14:27 
Nimm nicht das OnWork von Form1 sondern deklariere das ganze für den TThread.

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
Hendi48 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 271



BeitragVerfasst: Fr 24.08.07 15:01 
ok, danke es scheint jetzt zu funktionieren. Nur die ProgressBar fängt erst nach so 10s an sich zu füllen (ich seh aber das es schon downloadet in cFos Speed). Kann ich noch irgendwie machen das die sofort von Anfang an sich füllt?