Entwickler-Ecke
Internet / Netzwerk - DownloadThread stoppt einfach
Hendi48 - Do 23.08.07 18:19
Titel: DownloadThread stoppt einfach
Hi,
ich habe einen DownloadThread:
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:
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:
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 - 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 - 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 - Fr 24.08.07 13:54
Moin!
Hendi48 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
Hendi48 - Fr 24.08.07 14:17
ok, ich hab Mainform.Onwork jetz so umgeändert:
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 - Fr 24.08.07 14:27
Nimm nicht das OnWork von Form1 sondern deklariere das ganze für den TThread.
Hendi48 - 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?
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!