Newsgroup: it.comp.lang.delphi
Titolo: Findfirst e findnext. LENTE...

Ciao
Uso le funzioni findfirst e findnext per scorrere i file della cartella
documenti recenti.
Devo memorizzare su tab dbaseIV gli ultimi 50 documenti aperti controllando
la data dell'ultimo accesso.
A livello di codice è tutto ok, provato e funzionante sia su XP Professional
che su Win 98.
Il mio problema però è che questa operazione è MOLTO lenta (4 o 5 secondi),
durante i quali, il sistema si "impalla", in quanto questo programma gira in
background e la procedura in questione è sotto timer(60sec). Qualcuno sà
indicarmi funzioni, o componenti che permettono di scorrere i file di una
cartella in modo + rapido? Non vorrei cancellare ogni volta i file della
cartella documenti recenti per aggirare il problema.
Ciao e grazie
Andrea
procedure tform1.recenti;
  var
    sr:tsearchrec;
    q:TQuery;
    righe:integer;
    esci:boolean;
begin
  esci:=false;
  q:=tquery.Create(application);
  q.Close ;
  q.DatabaseName := database;
  if findfirst(sys.Recent + '\*.*',faanyfile,sr) = 0  then begin  // primo
if
    if length(
sr.name
) >= 5 then begin
      q.SQL.Text :='SELECT * FROM "RECENTI.DBF" WHERE NOMEFILE = :p0';
      q.Params[0].AsString := copy(
sr.name
,1,length(
sr.name
) - 4);
      q.Open ;
      if not q.Eof then begin
        //update perchè esiste
        q.Close ;
        q.SQL.Text :='UPDATE "RECENTI.DBF" SET DATA = :p0, DATAINT = :p1
WHERE NOMEFILE = :p2';
        q.Params[0].AsString :=
datetimetostr(GetFileLastAccessTime(sys.recent + '\' + 
sr.name
));
        q.params[1].AsString :=currtostr(GetFileLastAccessTime(sys.recent +
'\' + 
sr.name
));
        q.params[2].AsString := copy(
sr.name
,1,length(
sr.name
) - 4);
        q.ExecSQL ;
        q.Close ;
       end
       else begin
        //insert perchè non esiste
        q.Close ;
        q.SQL.Text :='INSERT INTO "RECENTI.DBF" (NOMEFILE, DATA, DATAINT)
VALUES (:p0, :p1, :p2)';
        q.Params[0].AsString := copy(
sr.name
,1,length(
sr.name
) - 4);
        q.Params[1].AsString :=
datetimetostr(GetFileLastAccessTime(sys.recent + '\' + 
sr.name
));
        q.Params[2].AsString := currtostr(GetFileLastAccessTime(sys.recent +
'\' + 
sr.name
));
        q.ExecSQL ;
        q.Close ;
      end;
      q.Close ;
    end;
    while findnext(sr) = 0 do begin   //a
      if length(
sr.name
) >= 5 then begin //aa
        q.SQL.Text :='SELECT * FROM "RECENTI.DBF" WHERE NOMEFILE = :p0';
        q.Params[0].AsString := copy(
sr.name
,1,length(
sr.name
) - 4);
        q.Open ;
        if not q.Eof then begin
          //update perchè esiste
          q.Close ;
          q.SQL.Text :='UPDATE "RECENTI.DBF" SET DATA = :p0, DATAINT = :p1
WHERE NOMEFILE = :p2';
          q.Params[0].AsString :=
datetimetostr(GetFileLastAccessTime(sys.recent + '\' + 
sr.name
));
          q.params[1].AsString := currtostr(GetFileLastAccessTime(sys.recent
+ '\' + 
sr.name
));
          q.params[2].AsString := copy(
sr.name
,1,length(
sr.name
) - 4);
          q.ExecSQL ;
          q.Close ;
         end
         else begin
          //insert perchè non esiste
          q.Close ;
          q.SQL.Text :='INSERT INTO "RECENTI.DBF" (NOMEFILE, DATA, DATAINT)
VALUES (:p0, :p1, :p2)';
          q.Params[0].AsString := copy(
sr.name
,1,length(
sr.name
) - 4);
          q.Params[1].AsString :=
datetimetostr(GetFileLastAccessTime(sys.recent + '\' + 
sr.name
));
          q.Params[2].AsString := currtostr(GetFileLastAccessTime(sys.recent
+ '\' + 
sr.name
));
          q.ExecSQL ;
          q.Close ;
        end;
        q.Close ;
      end;  //aa
    end;  //a
  end;  //primo if
  findclose(sr);
      // manutenzione tabella MAX 50 record   delete min di dataint
  repeat
    q.Close ;
    q.sql.Text :='SELECT COUNT(NOMEFILE) AS RIGHE FROM "RECENTI.DBF"';
    q.Open ;
    righe:= q.fieldbyname('RIGHE').asinteger;
    q.Close ;
    if righe <= 50 then
      esci:=true
     else begin
      q.sql.Text := 'DELETE FROM "RECENTI.DBF" WHERE DATAINT = (SELECT
MIN(DATAINT) FROM "RECENTI.DBF")';
      q.ExecSQL ;
      q.Close ;
    end;
  until esci;
end;

 cartella in modo + rapido?
[CUT]
Ciao, spero ti sia d'aiuto sapere ke la funzione Application.ProcessMessages
fa in modo che durante i cicli non si abbia l'effetto di "pc impallato" ....
facci sapere!
Leo :)

tra gli esempi di delphi esiste la virtual listview che fa uso della
interfaccia IShellItem.
X la cronaca, gestione risorse basa parte del suo funzionamento su questa
interfaccia.
Il programmino non è di facilissima comprensione, ma credo che tu
studiandolo possa trovare una soluzione alternativa a quella che utilizza
attualmente.
Bye
A.

fa in modo che durante i cicli non si abbia l'effetto di "pc impallato"
....
Attenzione!
La processmessage fa in modo che il sistema processi eventuali messaggi in
coda.
L'unico problema è che se la metti ad esempio all'interno di un ciclo
rallenta le prestazioni in modo sensibile.
Infatti, un trucco consiste nel mettere del codice per fare in modo che la
processmessages non venga eseguita ad ogni iterazione:
for i:= 0  to 100000 do begin
  inc(j);
  if j =1000 then
    Application.ProcessMessages;
  FaiQualcosa;
  FaiQualcosaltro;
end;
Bye
A.

 rallenta le prestazioni in modo sensibile.
verissimo... cmq come in ogni cosa, dipende da cosa devi fare.
cmq grazie x la precisazione.
byte
Leo :)

 Andrea
ma mica si impalla tutto il sistema. Solo il tuo programma immagino.
A parte la soluzione proposta da Alberto, che ti devi un po'
studiare......potresti inserire il blocco di codice in un thread per non
bloccare quello principale.
In questo modo è il thread che esegue la tua procedura mentre quello
principale se ne sta tranquillo.
Ti saluto
Antonio

 ha scritto nel messaggio
news:1yg39.37012$lu5.1...@twister1.libero.it...

Non credo sia quello che serve a me...
Il programmino in questione mentre svolge questa procedura, non fa
nient'altro,
mentre windows per un istante non risponde(4 , 5 sec).
Ho provato a settare
  setPriorityClass(GetCurrentProcess,IDLE_PRIORITY_CLASS)
e sembra che giri tutto un pò meglio, anche se non ho ben capito cosa fa di
preciso questa funzione e , soprattutto se posso gestrirla a runtime o, devo
per forza settarla a designtime
Comunque grazie mille
Andrea