22. december 2003 - 19:20Der er
18 kommentarer og 1 løsning
Program fryser under udførsel af funktion
Jeg har lavet et program der kan overfører filer fra den en computer til en anden. Men når selve overførslen finder sted fryser programmet, så man ikke kan gøre noget. Selve overførsels funktionen ligger i en separat unit der ikke hører til nogen form. Kan man på en eller anden måde få gjort således at resten af programmet ikke fryser når det overfører en fil?
Jeg har absolut ingen forstand på Delphi, men det lyder som om du KUN har een enkelt tråd kørende. Så du skal oprette en ny tråd, som skal stå for at udføre fil-overførslen... Sådan så du ikke optager din Main-tråd, som står for at lytte på GUI-forespørgslen og paint'e din form :-)
Håber svaret kunne bruges til noget :-)
Synes godt om
Slettet bruger
22. december 2003 - 19:23#2
Hvis du bruger et loop til at kopier med kan du sætte Application.ProcessMessage; ind i loopet, ellers tror jeg du skal lave en thread til funktionen.
okay ja jeg tror jeg har regnet ud at det handler om noget tasking.
hejhej>>> Application.ProcessMessages; kan jeg ikke lige få til at virke ... hvis du mener det er løsningen kan du så ikke lige lave lidt sovesekode med et eksempel jeg kan kigge på !?
Synes godt om
Slettet bruger
22. december 2003 - 19:53#4
Lidt svært at komme med noget kode du kan bruge, men bliver brugt i nogle at koderne her:
ja okay ... her er lidt kode, dog ved jeg ikke til hvormeget hjælp det er.
Procedure tformdl.download(socket:TCustomWinSocket;filename:string; filesize:integer); begin savedialogfl.InitialDir:='c:\'; if savedialogfl.Execute=true then begin formdl.Lblfilename.Caption:=formexp.activefile; formdl.Lbltimeout.caption:='No Timeouts'; formdl.Show; filetranspro(socket,savedialogfl.FileName,filesize); end; end;
procedure filetranspro(socket:TCustomWinSocket;path:string;filesize:integer); Var F : TFileStream; iLen, counter, size, i: Integer; Bfr: Pointer; halt :boolean; begin F := TFileStream.Create(path, fmCreate or fmShareDenyWrite); iLen := Socket.ReceiveLength; GetMem(Bfr, iLen); size:=0; i:=0; halt:=true; try formdl.StatusBardl.Panels.Items[0].Text:='Downloading'; while halt do begin counter:=Socket.ReceiveBuf(Bfr^, iLen); if counter=-1 then begin inc(i); formdl.Lbltimeout.Caption:='Timeout nr. '+inttostr(i)+' of 3'; sleep(30); if i=3 then halt:=false; end else begin F.WriteBuffer(Bfr^, counter); size:=size+counter; formdl.Lbltimeout.caption:='No Timeouts'; i:=0; end; end; finally FreeMem(Bfr); FreeAndNil(f); formdl.StatusBardl.Panels.Items[0].Text:='Download complet' form1.Memotext.Lines.Add(inttostr(size)+' bytes just received and saved as '+form1.Edsavepath.text); end; end;
Jeg har prøvet at indsætte application.processmessages; inde i while løkken men det resulterede i at filoverførsels funktionen ikke virkede og den kørte underlig nok tformdl.download to gange.
Synes godt om
Slettet bruger
23. december 2003 - 17:15#8
Prøv at sætte Application.ProcessMessage; ind over counter:=Socket.ReceiveBuf(Bfr^, iLen);
tillon >> Du skal implementere en klasse der arver fra TThread og i den execute procedure skal du lave dir kopiering. Når du så vil kopiere din fil kalder du blot din tråd. På denmåde kan du både lave progress, og tids estimater UDEN du låser resten af din applikation.
Med andre ord ligger jeg mig 100% op af corholio og doc404 Jens B
ohhh ja jamen jeg takker .. nu skal jeg bare lige lære hvordan man bruger TThread ordentlig ... Men det kan man jo læse sig til. Jeg beder dem, der føler sig berettiget til point, kaste et svar så jeg kan uddele lidt julegaver ! ;)
procedure tformdl.download(socket : TCustomWinSocket; filename : string; filesize : integer); begin savedialogfl.InitialDir:='c:\'; if savedialogfl.Execute=true then begin formdl.Lblfilename.Caption:=formexp.activefile; formdl.Lbltimeout.caption:='No Timeouts'; formdl.Show; filetranspro(socket,savedialogfl.FileName,filesize); end; end;
procedure filetranspro(socket : TCustomWinSocket; path : string; filesize : integer); var F : TFileStream; iLen, counter, size, i: Integer; Bfr: Pointer; halt :boolean; begin F := TFileStream.Create(path, fmCreate or fmShareDenyWrite); iLen := Socket.ReceiveLength; GetMem(Bfr, iLen); size:=0; i:=0; halt:=false; try formdl.StatusBardl.Panels.Items[0].Text:='Downloading'; while not halt (* and (counter <> iLen) *) do begin counter := Socket.ReceiveBuf(Bfr^, iLen); if counter = -1 then begin // Error (helloooo???) inc(i); formdl.Lbltimeout.Caption:='Timeout nr. '+inttostr(i)+' of 3'; sleep(30); halt := i = 3; end else begin // OK (chatting) F.WriteBuffer(Bfr^, counter); inc(size,counter); formdl.Lbltimeout.caption:='No Timeouts'; i:=0; // Reset counter
Application.ProcessMessages; // Update and give space to others end; end; finally FreeMem(Bfr); FreeAndNil(f); formdl.StatusBardl.Panels.Items[0].Text:='Download completed'
// Not calling another form anymore! fStrings.Lines.Add(inttostr(size)+' bytes received and saved to '+path); end; end;
I øvrigt er det en grim, grim uskik at kalde komponenter i andre forme, såsom der hvor du fylder ting i form1.memotext (og i øvrigt henter filnavnet derfra selvom det er sendt med som parameter). Der er andre og bedre måder, tænker man objektorientereret så ved TFormDL ikke noget om TForm1 så der bør tænkes anderledes. Jeg ville løse det ved at lave en ny constructor til TFormDL sådan som jeg har lavet her.
Desuden skal du ikke have en halt-variabel der virker direkte modsat! Jeg har ikke afprøvet ovenstående rettelser, men det er der jeg ville proppe dem ind hvis ikke man skulle prøve at arbejde med tråde i stedet...
Kan ikke se hvordan du kommer ud af løkken når en kopiering lykkes. Mangler lidt i din while-linie.
Sidst burde du ikke allokere hele blokken af data - hent i bidder så du ikke støder på et eller andet allokeringsloft.
tja det er bare min nåde at sikre mig at der er noget data at overføre ... du kan vel kalde det min timeout funktion ... det er også den der sørger for at løkken brydes når filen er downloadet!
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.