Avatar billede tillon Nybegynder
22. december 2003 - 19:20 Der 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?
Avatar billede Slettet bruger
22. december 2003 - 19:23 #1
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 :-)
Avatar billede 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.
Avatar billede tillon Nybegynder
22. december 2003 - 19:39 #3
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å !?
Avatar billede 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:

http://www.swissdelphicenter.ch/torry/showcode.php?id=330
Avatar billede fixxxer Nybegynder
23. december 2003 - 14:31 #5
gør noget alá:

for filer := 0 to listemedfilerderskalkopires.count do begin
  application.processmessages;
  kopierblabla();
end;
Avatar billede fixxxer Nybegynder
23. december 2003 - 14:32 #6
hvis du gav os lidt kode er det i øvrigt nemmere at hjælpe :)
Avatar billede tillon Nybegynder
23. december 2003 - 17:12 #7
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.
Avatar billede Slettet bruger
23. december 2003 - 17:15 #8
Prøv at sætte Application.ProcessMessage; ind over counter:=Socket.ReceiveBuf(Bfr^, iLen);
Avatar billede tillon Nybegynder
23. december 2003 - 17:25 #9
desvære nej ... det gør at den f***er op totalt
Avatar billede Slettet bruger
23. december 2003 - 17:34 #10
Kommer der nogle fejl??
Avatar billede doc404 Novice
23. december 2003 - 17:58 #11
Brug TThread til sådan noget - det er det eneste rigtige. Du kan finde eksempler i hjælpen.
Avatar billede tillon Nybegynder
23. december 2003 - 18:01 #12
hejhej>>> nej der kommer ikke nogen fejl ... men programmet virker bare ikke når man gør det på den måde
Avatar billede borrisholt Novice
24. december 2003 - 11:20 #13
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
Avatar billede tillon Nybegynder
25. december 2003 - 00:34 #14
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 ! ;)
Avatar billede hrc Mester
25. december 2003 - 23:22 #15
Generelle kommentarer... Se nederst.

constructor Create(aOwner : TComponent; aStrings : TStrings);
begin
  inherited Create(aOwner);
  fStrings : aStrings;
end;

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.
Avatar billede kfz Nybegynder
03. januar 2004 - 13:39 #16
hvorfor bruger du sleep(30)????
Avatar billede tillon Nybegynder
03. januar 2004 - 14:45 #17
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!
Avatar billede forfatterksl Nybegynder
27. januar 2004 - 10:48 #18
Kunne det hjælpe at flytte din function over i den unit, der bruger den. Husk at stille den FØR procedurerne.
Avatar billede tillon Nybegynder
19. februar 2004 - 22:46 #19
Lukker ......
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester