ďťż

Ładny brzuch

Witam,
mam w programie w Delphi 2 wątki, które chcę wykonywać równocześnie, a do tego Form ma działać niezależnie od nich. Na początku miałem 1 wątek, działało bez zarzutu.
Ale teraz dodałem drugi używający IdFTP do pobrania pliku i zamiast działać równolegle, łączenie z serwerem przez FTP zawiesza okienko do czasu, aż się nie połączy (widać to m.in. po nie działaniu przez ten czas Timera, klepsydrze itd). Dlaczego tak jest i co zrobić, by te 3 procesy - wątek 1, wątek 3 i normalne działanie programu - działały równocześnie?

type TWatek = class(TThread) private { Private declarations } protected procedure Execute; override; public constructor Create(); end; type TWatekPobieraniaFTP = class(TThread) private procedure Polacz; protected procedure Execute; override; public constructor Create(); end;

procedure TForm1.FormCreate(Sender: TObject); begin IdFTP1.Port:= 21; IdFTP1.Username := 'user'; IdFTP1.Password := 'pass'; IdFTP1.Host := 'host'; SHGetSpecialFolderPath(0, cache, CSIDL_INTERNET_CACHE, False); if FileExists(cache+'\stopnie.txt') then DeleteFile(cache+'\stopnie.txt'); Form1.Timer1.Enabled:= True; Watek3:= TWatekPobieraniaFTP.Create(); Watek1:= TWatek.Create(); end; procedure TForm1.Timer1Timer(Sender: TObject); begin if ProgressBar1.Position = 100 then ProgressBar1.Position:= 0; ProgressBar1.Position:= ProgressBar1.Position + 1; end;

constructor TWatek.Create(); begin inherited Create(False); OnTerminate:= Form1.KoniecWatkuPobierania; end; procedure TWatek.Execute; var url, gdzie :PAnsiChar; begin FreeOnTerminate := True; Pobieranie[3]:= False; url:= PAnsiChar('http://' + Form1.IdFTP1.Host + '/stopnie.txt'); gdzie:= PAnsiChar(cache + '\stopnie.txt'); if URLDownloadToFile(Nil, url, gdzie, 0, Nil) <> 0 then Pobieranie[1]:= False else Pobieranie[1]:= True; Pobieranie[1]:= False; Pobieranie[3]:= True; end; constructor TWatekPobieraniaFTP.Create(); begin inherited Create(False); OnTerminate:= Form1.KoniecWatkuPobierania; end; procedure TWatekPobieraniaFTP.Execute; begin FreeOnTerminate := True; Pobieranie[4]:= False; Synchronize (Polacz); Pobieranie[4]:= True; end; procedure TWatekPobieraniaFTP.Polacz; begin try Form1.IdFTP1.Connect(); finally end; if Form1.IdFTP1.Connected then begin Pobieranie[2]:= True; try Form1.IdFTP1.Get('stopnie.txt', cache+'\stopnie.txt'); except Pobieranie[2]:= False; end; Form1.IdFTP1.Disconnect; end else Pobieranie[2]:= False; end;

bardzo proszę o pomoc, to dla mnie dość ważne.



rozumiem że chcesz obsługę FTP w wątku. W takim razie musisz obiekt odpowiedzialny za połączenie (u Ciebie : TIdFTP) tworzyć również w wątku.
Dlaczego? Bo "synchronize" zawiesza program, wykonuje jakby kod w głównym wątku. Z kolei nie możesz się odwoływać do komponentu z formy poza Synchronize ;)

Do pracy z komponentami IdFTP i IdHTTP możesz zastosować komponent o nazwie TIdThreadComponent
dzięki któremu w krótkim czasie łatwo uniknąć przywieszania się aplikacji.

Uczycie banalnie proste, w zdarzeniu Run komponentu dajemy np.
try IdHTTP1.Get() . . . finally IdThreadComponent.Stop

i wtedy wszystko ładnie możemy zsynchronizować ;)

PS: Komponenty Indy są strasznie mało przyjazne...
// zgadzam się ... -m

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • zsf.htw.pl
  •