Newsgroup: it.comp.lang.visual-basic
Titolo: Form durante un ciclo

Come posso evitare che, durante un ciclo For..Next con VB6,
la form non risponda più ai comandi?
Nel senso che se passo a un'altra applicazione nell'attesa che
il ciclo termini, quando torno sulla form iniziale la vedo come
disabilitata se provo a spostarla ci riesco solo a scatti...
Chiedo scusa per la domanda da profano...
Nel ciclo For...Next ovviamente ho inserito un DoEvents.
Grazie.

 ha scritto nel messaggio 
news:Pmsie.1383$Jd....@tornado.fastwebnet.it...

Ho avuto il tuo stesso problema, purtoppo sembrerebbe che tutte le 
istruzioni di ciclo in VB impegnino pesantemente l'applicazione ovvero il 
RUNTIME, nel senso che il sistema tenta di terminarli nel piu breve tempo 
possibile ma a scapito però di tutte le funzioni grafiche ovvero il redraw, 
il refresh e funzioni annesse al quale sembra che venga sottratto quasi 
totalmente tutto il tempo macchina, ma solo nei form aperti 
dall'applicazione che li usa (in parole povere la tua), se noti infatti le 
altre applicazioni che magari stai utilizzando in multitask tuttavia non 
risentono del problema, ma veniamo al dunque.
I cicli come ''for e next'' di solito vengono utilizzati quando è noto il 
numero di volte che il ciclo deve essere ripetuto, un conto e che tu faccia 
ad esempio:
for Counter=1 to 1000
.'tuo codice
next
Cicli di questo tipo, vengono eseguiti magari in un secondo, ma se si inizia 
a nidificare cicli dentro altri cicli allora
questi tempi aumentano notevolmente ed è appunto così che io ho riscontrato 
i tuoi stessi inconvenienti, scandivo infatti file lunghi centinaia di mega 
byte per byte per una mia applicazione ed avevo inserito anche una barra di 
progresso che si piantata subito dopo circa 10 secondi nonostante io avessi 
inserito l'istruzione .REFRESH che doveva mantenere l'oggetto aggiornato 
durante la scansione di questo file.
Dopo un momento di sbigottimento totale, mi venne l'idea di usare l'oggetto 
timer fissato all' intervallo minimo 1 millisecondi, tuttavia questo mi ha 
costretto
a cambiare tutta la struttura del mio algoritmo, ma ha risolto tutti i 
problemi correlati a cicli troppo lunghi della durata maggiore di un secondo 
che imprgnano il runtime eccessivamente, magari in VB NET questi problemi li 
hanno risolti ma non ci scommetterei, ecco un esempio di come io ho risolto 
sto casino:
1) Tu crei nel form interessato un timer ovviamente questo deve essere 
normalmente fermo, per cui già nelle sue proprietà alla voce ENABLED imposta 
False.
2) Inizializzi le tue variabili di inizio e fine conteggio supponiamo nel 
FORM1
SUB Form1_LOAD
                                           ' le definizioni le omettiamo 
quelle le conosci magari anche meglio di me quindi inizializziamo 
direttamente comer simulare il for next
Timer1.Interval=1                ' Qui come per Enabled o magari già nelle 
proprietà del timer fissi l'intervallo di intervento al minimo possibile in 
VB 1 millisecondi
Counter=1                           ' Questa variabile conterà  come se 
fosse dentro il ciclo FOR dell'esempio di cui sopra
HighLimit = 1000000000     ' Qui fisserai per dire il limite del tuo 
conteggio (che se fosse così lungo ti crea appunto i problemi che lamenti 
con FOR NEXT)
END SUB
3)  Ora succede questo la tua routine la eseguirai dentro il timer ad ogni 
scadenza dell intervallo ecco il codice come dovrebbe diventare, e fingiamo 
che il ciclo
debba partire quando clicchi ad esempio un pulsante:
Private Sub Command1_Click()
Timer.Enabled=True
End Sub
4 ) hai avviato il timer che contiene il tuo FOR NEXT simulato come i 
bambini dell'asilo
Private Sub Timer1_Timer()
Counter=Counter+1 
' la variabile inizia e continua il suo conteggio
. ' tuo codice, facci ciò che ti pare con COUNTER
. ' tuo codice, facci ciò che ti pare con COUNTER
. ' tuo codice,  facci ciò che ti pare con COUNTER
If Counter=HighLimit then Timer.Enabled=False                  ' é stata 
raggiunta la fine del conteggio e arresti il timer
End Sub
Ecco, che soluzione ho utilizzato io con successo per rimpiazzare il FOR 
NEXT, in pratica succede questo, tra un intervallo e l'altro del Timer
Il sistema non è totalmente impegnato come in FOR NEXT, ma lo è solo per un 
millisecondo + il tempo di eseguire la tua ruotine ad ogni intervallo
e per quanto strano possa sembrare questo lascia respirare di piu il RUNTIME 
di VB che avra quindi il tempo per i vari REFRESH, REDRAW
e altri aspetti graficici correlati come il trasninamento del Form con la 
barra, un consiglio se vedi che 1 millisecondo e troppo poco prova con 2 o 5 
o 10. nella mia ignoranza questo è l'unico modo che ho trovato, non sò se 
poi con le API di windows esisteno soluzioni che non ti costringano a 
rinunciare al For Next, così com,'è.
Inoltre ti segnalo che tutti i cicli anche WHILE WEND e compagnia bella 
risentono tutti dello stesso problema se non riescono ad essere eseguiti in 
tempi dell'ordine di 5 o 10 secondi al massimo.
Spero che il tuo algoritmo non sia talmente complesso da renderti troppo 
difficile l'applicazione di questo metodo !!!
Salutoni e buona fortuna !!!
Ivan


L'intervallo minimo lo puoi tranquillamente impostare anche a 50 - 60 
ms, tanto più basso di così non puoi andare .... ( per la precisione 
1/18 di secondo ,circa 56 ms)
dai un'occhiata su...
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon98/html/vbcontimercontrol.asp
Ciao,
Roby

 ovvero il RUNTIME
[SNIP]
Questo non e' un problema di VB e nemmeno dei cicli FOR e WHILE di per se 
stessi: in una applicazione con un singolo thread, se "spari" un ciclo molto 
lungo, il tempo del processore assegnato viene impegnato ad eseguire quelle 
istruzioni (d'altra parte e' esattamente quello che il tuo codice ha 
chiesto)
L'utilizzo del DoEvents e' piu' che sufficente per restituire 
temporaneamente il controllo al S.O. che puo' occuparsi delle operazioni di 
disegno base, la ricezione di messaggi (eventi in VB) ecc.
Come viene spesso ripetuto qui sul NG, anche DoEvents va pero' usato con 
cognizione di causa, perche' un ciclo
For i = 1 To 1000000
    [piccolo blocco di codice rapido]
    DoEvents
Next
rende si l'applicazione responsiva, ma rallenta notevolmente il tempo totale 
di completamento del ciclo, ed impegna comunque al massimo il processore, 
viceversa una situazione come questa
For i = 1 To 1000000
    [grosso blocco di codice lento]
    DoEvents
Next
fa si che il tempo che passa tra un DoEvents e l'altro sia comunque troppo 
lungo, e quindi l'effetto e' ancora quello di finestra bloccata e refresh a 
scatti, che si lamentava nel messaggio originale
Non entro nel merito di tutto il discorso sul Timer, ma se non c'era qualche 
problema specifico, ho il sospetto che tu abbia sparato ad una mosca con un 
cannone...
Ciao
-- 
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown 

Ciao Luca, ammetto l'ignoranza mia che non conoscevo affatto il comando 
DoEvents, io il basic l'ho imparato da un C64 per la prima volta e in Qbasic 
poi, tutti ambienti non grafici, ovviamente quindi passando a VB non mi ero 
mai posto il problema anzi pensavo che comportamenti come il DoEvents 
fossero già automatici nel runtime di VB ma vedo che mi sbagliavo, hanno 
quindi creato il DoEvents per tentare di sopperire a questo problema, così 
ove serve si usa, beh, evviva la sapienza allora, hai proprio ragione, non 
trovando altre soluzioni solo il timer mi ha potuto aiutare ma ho pagato il 
prezzo di dover cambiare l'algoritmo e per mia ignoranza il timer è stato 
l'unico modo che ho trovato e come tu dici ho sparato proprio ad una mosca 
con un cannone :-), ora che ho capito di che si tratta credo che se 
posizionata in un punto strategicamente intermedio anche in cicli nidificati 
il problema che lamentava Gigino dovrebbe sparire, tuttavia lo terrò 
presente anche per me stesso tutto questo.
Ciao :-)