Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
Delphi - Applicare più processi contemporaneamente
Forum - Delphi - Applicare più processi contemporaneamente

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
a_butta (Member)
Expert


Messaggi: 578
Iscritto: 16/03/2010

Segnala al moderatore
Postato alle 13:50
Lunedì, 19/04/2010
Ciao a tutti.
Il mio problema riguarda l'esecuzione di più processi contemporaneamente.
Ho un programma che oltre a svolgere altre funzioni copia dei determinati file da una cartella all'altra con relativa ProgressBar e label indicante l'avanzamento.
Soltanto che quando inizia a copiarmi il file sembra che la finestra si blocchi e non mi lascia usare il programma finchè non abbia finito... Oltre a questo la progressbar diventa invisibile non perchè non funziona ma perchè proprio si arresta il programma, come se lavorasse "da solo" per riapparire alla fine della copiatura...
Come posso ovviare a questo problema?

Grazie mille

PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6202
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 14:18
Lunedì, 19/04/2010
Non si tratta di eseguire più processi, ma più thread all'interno del tuo processo.

Se il processo che esegue la copia lo fa utilizzando lo stesso thread di quello che si occupa del ridisegno della finestra, ecco che hai il problema di cui lamenti (o il thread fa la copia o ridisegna la finestra).

Se il thread che fa la copia, utilizza un ciclo, potresti forzare il thread stesso ad occuparsi ogni tanto del ridisegno con una chiamata come la DoEvents per il VB (non so se in Delphi esiste qualcosa del genere). Se il thread è bloccato su una singola API, allora l'unico modo è creare un altro thread che si occupi della copia, lasciando il thread dell'interfaccia libero di lavorare.


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti (uno dei padri fondatori del moderno Calcolo delle probabilità) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
a_butta (Member)
Expert


Messaggi: 578
Iscritto: 16/03/2010

Segnala al moderatore
Postato alle 14:23
Lunedì, 19/04/2010
mmmh... bene... è la prima volta che sento parlare di thread...
Come si fa a "creare" un altro thread?

PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6202
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 14:27
Lunedì, 19/04/2010
Testo quotato

Postato originariamente da a_butta:

mmmh... bene... è la prima volta che sento parlare di thread...



Non bene ... l'argomento thread non è semplicissimo e se non ne hai sentito mai parlare, non mi sembra il caso di affrontarlo in una risposta di un forum ...

Testo quotato

Come si fa a "creare" un altro thread?



Forse questa guida

http://programmazione.html.it/guide/lezione/1231/sviluppo- ...

potrà aiutarti ... altrimenti, dovrai munirti di un buon testo (come ti consiglio di fare) e imparare con pazienza e applicazione ...


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti (uno dei padri fondatori del moderno Calcolo delle probabilità) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
()
Newbie


Messaggi:
Iscritto:

Segnala al moderatore
Postato alle 15:28
Lunedì, 19/04/2010
Dato che usi lazarus prendi questi due link:

http://www.freepascal.org/docs-html/prog/progch10.html#x22 ...


http://wiki.lazarus.freepascal.org/Multithreaded_Applicati ...


Tutte queste informazioni le ho studiate da solo e non da qualcuno.
Quindi informati meglio dopo averle lette.

A me sembra che tu non abbia capito bene il concetto di processo:
brevemente ,un processo e' come un programma in esecuzione unito alle sue informazioni di stato(memoria ,registri,I/O , ecc..).

Il thread praticamente  o e' il processo stesso,quando non ne crei,o e' una parte di un processo che condivide con lui tutte le sue informazioni.(ricordando che l'altra parte di processo e' anche essa un thread).

La difficolta' nell'uso dei thread sta nel sincronizzarli: per esempio devi stare attento al loro accesso alla memoria: infatti se due thread acceddono nello stesso momento ad uno stesso contenuto creano dei problemi all'esecuzione del programma.

Ultima cosa e' che quando crei un nuovo thread esso non occupa nuova memoria,ma condivide la stessa del processo. Ed e' questo che li rende tanto efficenti.(oltre sicuramente a svolgere lavoro in contemporanea come se si avessero piu' processori).



Ultima modifica effettuata da il 19/04/2010 alle 15:43
PM Quote
Avatar
a_butta (Member)
Expert


Messaggi: 578
Iscritto: 16/03/2010

Segnala al moderatore
Postato alle 18:20
Lunedì, 19/04/2010
grazie mille delle informazioni. Sei stato veramente gentile.:hail:

Io ho provato a buttare giù un codice per la copiatura dei file. L'ho fatto prima in Delphi7 e poi l'ho portato su Lazarus. Nel primo funziona alla grande. Il secondo invece mi blocca letteralmente il computer: devo resettarlo.
Posto il codice:

Codice sorgente - presumibilmente Delphi

  1. unit saveunit;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  9.   ComCtrls, StdCtrls;
  10.  
  11.   var Source,Destination: string;
  12.  
  13. type
  14.  
  15.   { TSaveForm }
  16.  
  17.   TSaveForm = class(TForm)
  18.     Label1: TLabel;
  19.     Label2: TLabel;
  20.     ProgressBar1: TProgressBar;
  21.     procedure FormCreate(Sender: TObject);
  22.     procedure FormShow(Sender: TObject);
  23.     procedure ProgressBar1ContextPopup(Sender: TObject; MousePos: TPoint;
  24.       var Handled: Boolean);
  25.  
  26.   private
  27.     { private declarations }
  28.   public
  29.     { public declarations }
  30.   end;
  31.  
  32. type  TCopyProcedure = class(TThread)
  33.      private
  34.      public
  35.      protected
  36.      Procedure Execute; override;
  37. end;
  38.  
  39. var
  40.   SaveForm: TSaveForm;
  41.  
  42. implementation
  43.   uses mainunit;
  44. { TSaveForm }
  45.  
  46.  
  47. procedure TCopyProcedure.Execute;
  48. var
  49.   FromF,
  50.   ToF        : file of byte;
  51.   Buffer     : array[0..4096] of char;
  52.   NumRead    : integer;
  53.   FileLength : longint;
  54. begin
  55.   AssignFile(FromF,Source);
  56.   reset(FromF);
  57.   AssignFile(ToF,Destination);
  58.   Rewrite(ToF);
  59.   FileLength:=FileSize(Source);
  60.   SaveForm.Progressbar1.Max := FileLength;
  61.     while FileLength > 0 do
  62.     begin
  63.       BlockRead(FromF,Buffer[0],SizeOf(Buffer),NumRead);
  64.       FileLength := FileLength - NumRead;
  65.       BlockWrite(ToF,Buffer[0],NumRead);
  66.       SaveForm.Progressbar1.Position := SaveForm.Progressbar1.Position + NumRead;
  67.       SaveForm.Label2.Caption:= IntToStr(Trunc((SaveForm.Progressbar1.Position * 100)/SaveForm.Progressbar1.Max)) + ' %';
  68.     end;
  69.     CloseFile(FromF);
  70.     CloseFile(ToF);
  71.   ShowMessage('File Copiato con successo!');
  72.   SaveForm.ProgressBar1.Position:=0;
  73.   SaveForm.Close;
  74. end;



Da un'altra unit io imposto precedentemente i valori di Source e di Destination e poi lancio il comando:
Codice sorgente - presumibilmente Plain Text

  1. SaveUnit.TCopyProcedure.Create(False);



Risultato: errore in runtime. Non riesco a capire che errore è perchè proprio mi blocca il computer.

Riesci a trovarci qualche errore in quel codice?

Ultima modifica effettuata da a_butta il 19/04/2010 alle 18:21
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6202
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 19:47
Lunedì, 19/04/2010
Solo per la precisione ...

Testo quotato

Postato originariamente da Saladino:
Il thread praticamente  o e' il processo stesso,quando non ne crei,o e' una parte di un processo che condivide con lui tutte le sue informazioni.(ricordando che l'altra parte di processo e' anche essa un thread).



Un thread è un "percorso di esecuzione" tra i tanti disponibili per un processo.
Un processo è costituito almeno da un thread (sono concetti diversi) che viene creato automaticamente dal sistema operativo (un thread non e' il processo).
Non c'è "una parte e l'altra parte" dato che i thread possono essere tanti, sicuramente piu' di 2 ...

Testo quotato

Ultima cosa e' che quando crei un nuovo thread esso non occupa nuova memoria



Non è esattamente così ... un thread può occupare memoria indipendentemente da altri thread. Semmai si deve dire che i thread condividono lo stesso "spazio di indirizzamento" del processo.


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti (uno dei padri fondatori del moderno Calcolo delle probabilità) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
()
Newbie


Messaggi:
Iscritto:

Segnala al moderatore
Postato alle 7:46
Martedì, 20/04/2010
si era quello che intendevo.
Solo che tu sei stato più preciso.

Ultima modifica effettuata da il 20/04/2010 alle 7:48
PM Quote
Avatar
a_butta (Member)
Expert


Messaggi: 578
Iscritto: 16/03/2010

Segnala al moderatore
Postato alle 17:32
Martedì, 20/04/2010
Allora il codice funziona di per sè, solo che dato che io devo far passare i valori da una form a un altra ho fatto in questo modo: Dalla form principale ho impostato le variabili Source e Destination e poi ho inserito la chiamata SaveForm.Show.

Nella SaveUnit ho questo codice:

Codice sorgente - presumibilmente Delphi

  1. unit saveunit;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  9.   ComCtrls, StdCtrls;
  10. var Source, Destination: string;
  11. type
  12.  
  13.   { TSaveForm }
  14.  
  15.   TSaveForm = class(TForm)
  16.     Label1: TLabel;
  17.     LabelCount: TLabel;
  18.     ProgressBar1: TProgressBar;
  19.     procedure FormCreate(Sender: TObject);
  20.     procedure FormShow(Sender: TObject);
  21.   private
  22.     { private declarations }
  23.   public
  24.     { public declarations }
  25.   end;
  26.  
  27.   type
  28.       {Thread Copiatura}
  29.  
  30.   TCopyProcedure = class(TThread)
  31.      private
  32.      fStatusText : string;
  33.  
  34.     protected
  35.     procedure Execute; override;
  36. end;
  37.  
  38. var
  39.   SaveForm: TSaveForm;
  40.  
  41. implementation
  42.  
  43. { TSaveForm }
  44.  
  45. procedure TCopyProcedure.Execute;
  46. var
  47.     newStatus : string;
  48.     FromF,
  49.     ToF        : file of byte;
  50.     Buffer     : array[0..4096] of char;
  51.     NumRead    : integer;
  52.     FileLength : int64;
  53. begin
  54.   //TCopyProcedure.Synchronize ;
  55.   //fStatusText := 'TMyThread Running...';
  56.   AssignFile(FromF,Source);
  57.   reset(FromF);
  58.   ShowMessage(Destination);
  59.   AssignFile(ToF,Destination);
  60.   Rewrite(ToF);
  61.   FileLength:=FileSize(Source);
  62.   SaveForm.LabelCount.Caption := IntToStr(FileLength) ;
  63.   SaveForm.Progressbar1.Max := FileLength;
  64.     while FileLength > 0 do
  65.     begin
  66.       BlockRead(FromF,Buffer[0],SizeOf(Buffer),NumRead);
  67.       FileLength := FileLength - NumRead;
  68.       BlockWrite(ToF,Buffer[0],NumRead);
  69.       SaveForm.Progressbar1.Position := SaveForm.Progressbar1.Position + NumRead;
  70.       SaveForm.ProgressBar1 .Caption := IntToStr(SaveForm.ProgressBar1.Position );
  71.       SaveForm.Label1.Caption:= IntToStr((SaveForm.Progressbar1.Position *  SaveForm.Progressbar1.Max) div 10000) + ' %';
  72.     end;
  73.     CloseFile(FromF);
  74.     CloseFile(ToF);
  75.   SaveForm.Label1.Caption := ('File Copiato con successo!');
  76.   SaveForm.ProgressBar1.Position:=0;
  77.   Terminate;
  78. end;
  79.  
  80.  
  81. procedure TSaveForm.FormCreate(Sender: TObject);
  82. begin
  83.  
  84. end;
  85.  
  86. procedure TSaveForm.FormShow(Sender: TObject);
  87. begin
  88.   TCopyProcedure.Create (False);
  89. end;
  90.  
  91. initialization
  92.   {$I saveunit.lrs}
  93.  
  94. end.



Durante il debug non mi dà errore. Quando invece da runtime avvio la procedura, mi viene fuori il seguente errore:
Project nome.exe raised exception class 'EThread' with message CheckSyncronize called from non-main thread "$C78"

Le ultime tre lettere però variano ogni volta che esce il messaggio.

Non ho idea di come risolvere:d... potete aiutarmi?
Grazie...

Ultima modifica effettuata da a_butta il 20/04/2010 alle 17:33
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo