Newsgroup: it.comp.lang.delphi
Titolo: Thread - problema di progetto

Sto imparando e nei vari esperimenti fatti ho costruito una
classe che mi scannerizza l'HD costruendomi l'albero delle 
directory. Visto che questa è un operazione l0unga che tiene bloccata
la macchina per un paio di minuti l'ho messa su un thread e fin quà
funziona benissimo.
La funzione fra gli altri parametri
riceve il puntatore alla barra di scorrimento
e ad una label che viene aggiornata in base allo 
stato di avanzamento e piu ò meno ha
questa interfaccia:
TThreadScanDir = class(TThread)
....
  protected
    procedure Execute; override;
  published
    constructor CreateIt(....)
....
All'interno di execute fa le chiamate ad altre funzioni membro che
svolgono il lavoro.
Anche se questa soluzione mi funziona, non mi piace molto.
in questo modo è la classe a funzionare in tread e non le singole
funzioni membro.
Per esempio potrei volere che costruire delle funzioni membro
sul genere
EseguiScansione
SincronizzaDirectory
CopyAllFile
DeleteAllFile
ComprimiStruttura
che singolarmente funzionassero in tread.
Non sono stato in grado di trovare nessuna soluzione elegante che 
che mi permetta di riutilizzare con facilità il codice in un altro
progetto
Magari per voi è una cosa semplice, io non sono riuscito a trovare
documentazione sufficiente a chiarirmi le idee su questi argomenti.
Quindi sono ben accetti consigli del tipo leggi questo e quello....
(attenzione l'help di delphi e l'esempio l'ho gia visto, e mi ha
aiutato ad arrivare fino alla realizzazione attuale ma non ad andare
oltre)
Grazie per l'attenzione 
Zilo...@libero.it

che singolarmente funzionassero in tread.
Non mi sembra logicamente corretto.
Queste operazioni che elenchi sono tutte incompatibili l'una con
l'altra (se sto comprimendo il disco, non posso scandire le
directory, se sto scandendo, non posso copiare o cancellare i
file).
--
Andrea Laforgia - walkietalkie(at)
libero.it
#exclude <windows.h>

file).
Grazie per la risposta, ma mi devo essere spiegato male.
Non è che voglio lanciare queste procedure sull'HD contemporaneamente
(tra l'altro prima di applicare le altre operazioni dovrò aver
scansionato le directory e caricato il risultato in una treeview).
Quello che vorrei realizzare però è una classe che contenga queste
possibilità latenti per poterle richiamare a piacimento dall'esterno.
Inoltre la classe dovrebbe essere facilmente espandibile tramite il
metodo dell'ereditarietà.
La mia prima realizzazione 'pilota' lancia la sequenza delle
operazioni che mi servono nella funzione execute, ma questo mi
taglia le gambe per la riusabilita del codice.
Supponiamo che io voglia per esempio utilizzare la mia classe 
in una funzione che mi comprime tutti i file "*.bak" dalla macchina
Nella mia 1 versione che non atilizzava i thread (ma bloccava la
macchina per un minuto) potevo fare una funzioncina che utilizzava
la mia classe in questo modo
MioHD:=MiaClasse.Create(....,. c:\ , Indirizzo Barra ...)
MioHD.scansione(.*.BAK.... %BarraDiScorrimentoDaUtilizzare=30 )
MioHD.comprimi( %BarraDiScorrimentoDaUtilizzare=70 )
Poi se dopo averli compressi li voglio cancellare
mi costruisco un altro programma che includa la mia classe e la chiamo
con una altra sequenza
MioHD:=MiaClasse.Create(....,. c:\ , Indirizzo Barra ...)
MioHD.scansione(.*.BAK.... %BarraDiScorrimentoDaUtilizzare=80 )
MioHD.delete( %BarraDiScorrimentoDaUtilizzare=20 )
Utilizzando il Thread sono costretto a mettere tutto dentro alla
pocedura Execute e quindi se voglio utilizzare una sequenza di 
comandi diversa  devo fare una classe figlia e fare l'overload di
Execute. Come sistema mi sembra scomodo. 
Pensando a possibili soluzioni mi sono venuta alcune idea, ma tutte 
un pò fumose e molto macchiavelliche (devo buttar giù qualche
programma di prova per capire se sono realizzabili) Alla peggio
posso passare come parametro una stringa con la sequenza delle
operazioni che La funzione execute deve essere in grado di
interpretare ed eseguire (però mi fa un po schifo fare in questo
modo).
Accetto consigli.....
I nomi delle procedure che ho dato volevano essere puramente
la classe  che vorrei costruire
 indicativi
Non intendo eseguirle contemporaneamente (e ad ogni modo i nomi delle
procedure che ho 

metodo dell'ereditarietà.
A livello logico, i thread indicano delle operazioni da
compiere in modo indipendente e quello che tu vuoi fare e'
creare operazioni indipendenti.
Quindi, secondo me, bisogna rappresentare ogni azione con un
thread.
Quello che io farei e' creare una classe astratta base (o
forse sarebbe meglio un'interfaccia), chiamata
"TDiskOperation", che indica l'azione generica e che
ovviamente non deve essere istanziabile.
Questa classe deriva da TThread, perche' e' l'interfaccia di
ogni operazione.
Quando si vuol definire una nuova operazione, si deriva da
TDiskOperation (TScanDisk, TCompressFile, TCopyFile, ...).


TScanDisk, TCompressFile, TCopyFile
Avevo pensato diverse soluzioni alternative, ma alla fine non 
si sono rivelate realizzabili.
Quindi adesso in effetti sto già facendo questa trasformazione al mio
programma. Utilizzo la classe perchè l'Interfaccia ancora non l'ho
studiata, e poi il numero GUID univoco che dovrei utilizzare 
mi lascia perplesso, se qualcun altro per sfiga nera utilizza il mio
stesso GUID il mio programma non va in conflitto col suo?
Però la soluzione non mi sembra elegante (magari è una mia fissa)
Aspetta un momento mi pare di ricordare di alcuni typecast fatti in
modo implicito .... si forse è anche elegante.
Per ora sospendo la discussione, questa sera faccio un paio di
esperimenti poi ne riparliamo
Ciao.
 

stesso GUID il mio programma non va in conflitto col suo?
Hai piu' probabilita' di fare 6 al superenalotto che generare due GUID
uguali. A sto punto se fai 6 al superenalotto, chissenefrega di due
GUID uguali? :-)
Massimo
-- 
"Ciao Rex, che cavolo di situazione eh? Due dentro, due fuori, puo' succedere di tutto!"

stesso GUID il mio programma non va in conflitto col suo?
I GUID vengono generati in modo da essere univoci (o quasi).
In ogni caso la possibilita' di conflitto e' cosi' remota,
che puoi stare tranquillo (non so, poi, se ti serva
realmente un GUID in questo caso).


GUID uguali? :-)
eh eh, logica infallibile, dottor Spock :)

On Fri, 22 Jun 2001 08:41:36 GMT, Andrea Laforgia <xx...@xxxxx.xxx>
wrote:

256 ^16/numero di Guid che il mio prog potrŕ incontrare?
si viene circa un 3*10^38 /dividiamo pure per un milione di casi
sfigati
rimane sempre un  3*10^32 
contro un misero (90*89*88*87*86*85) / (1*2*3*4*5*6) contro una del
superenalotto
Ok mi avete convinto
Per il resto non ho terminato le prove e rimando a Lunedě
Grazie.

modo implicito .... si forse è anche elegante.
Sigh.....snif....
Ancora nulla.
Pensavo di poter promuovere un oggtto da
TDiskOperation verso TScanDisk tramite 
un typecasting, ma il compilatore non me 
lo consente (non ha tutti i torti). 
Potrei metterle tutte in cascata... ma non mi
ispira molta fidicia. Sul genere
TDiskOperation=class(thread)
TScanDisk=class(TDiskOperation)
TCompressFile=class(TScanDisk)
TCopyFile=class(TCompressFile)
TAllDiskOperation=class(TCopyFile)
e poi usarle in questo modo
var myclass:TAllDiskOperation;
begin
myclass:=TAllDiskOperation.create()
(myclass as TScanDisk).execute;
(myclass as TCompressFile).execute;
Ora mi sto studiando le interfaccie e vedo se mi riesce
di pensare un approccio migliore. a proma vista ho notato
degli esempi interessanti.

var myclass:TAllDiskOperation;
Scusa, ma la reputo una cosa a dir poco orrenda, oltre che
slegata del tutto da un filo logico.
Non capisco che problema ci sia nel definire un'interfaccia
TDiskOperation e delle classi che implementano
l'interfaccia, facendo l'override dei metodi base (virtuali
puri). 


 l'override dei metodi base (virtuali puri).
Scusami, ma a questo punto non capisco piů nemmeno io.
Probabilmente mi sono perso in un bicchiere d'acqua.
Mi ristudio il capitolo che parla di ereditarieta e mi rifaccio gli
esercizi. (il problema per ora lo sospendo, tanto non ho fretta mi serve
solo per imparare)
Ad ogni modo ti ringrazio per aver cercato di aiutarmi
Z80