Newsgroup: it.comp.lang.visual-basic
Titolo: DoEvents

Ciao a tutti!
Qualcuno sa spiegarmi perché l'utilizzo dell'istruzione DoEvents è
sconsigliato dalla stessa Microsoft? l'ho sentito dire in giro, non
vogliatemene se non è vero.
Grazie in anticipo
Ciao
Marco Minerva
http://www.geocities.com/SiliconValley/Foothills/7260/
http://www.armaditaggia.com/marco

...



Perche' cosi' dopo lo usano solo loro :-)
Vagli a dire che certe cose con VB funzionano SOLO se ci ficchi qualche
DoEvents!
--
Roal Zanazzi
z...@iol.it

sconsigliato dalla stessa Microsoft? ...
Dicevano lo stesso del GOTO e poi ci anno rifilato ON ERROR GOTO !
Bisogna stare solo attenti che mentre si fa lavorare una routine che
contiene DoEvents non si permetta di avviarne altre che potrebbero andare in
conflitto provocando loop infiniti.
Ciao
--
-
MIX (VB5SP3)
post...@yahoo.com
80 links ai siti VB
http://space.tin.it/computer/gaais
http://www.tempolibero.com/user/mix/
 (alternativo)
-


Anche se solo tenti di visualizzare qualcosa durante un ciclo (es. una
progress-bar) sei costretto ad usare DoEvents, altrimenti la finestre e la
progress-bar non vengono rinfrescate (refresh).
Questo non e' un problema del sistema (in altri linguaggi non sei costretto
a fare l'equivalente del DoEvents), ma di VB e della sua dannata
architettura interna.
--
Roal Zanazzi
z...@iol.it

Windows 95 e 98 sono pre-emptive nel senso che possono interrompere
un'applicazione 32 bit per dare il controllo ad un'altra.
Windows 3.x, invece, doveva attendere che l'applicazione chiamasse una
funzione di sistema (GetMessage o equivalenti in C) per poter riprendere il
controllo e passare l'esecuzione ad un'altra applicazione.
Se, pero', all'interno del mio programma faccio un bel loop senza mai
chiamare la GetMessage e DispatchMessage (sempre in C) i messaggi non
arrivano alla mia applicazione.
In Visual Basic il ciclo dei messaggi (get e dispatch) e' gestito da Visual
Basic (chissa' come). Va da se, pero', che se faccio un loop e' molto
probabile (ed infatti accade) che il programma non riceva altri messaggi. Ma
sarebbe giusto, ad esempio, poter accedere ad altre voci di menu' mentre io
sto elaborando qualcos'altro? Secondo me, no.
Se voglio forzare, all'interno di un loop, il ciclo dei messaggi devo
chiamare la DoEvents ed a quel punto ho il problema di dover disattivare
tutto cio' che l'utente non deve toccare.
Ciao.
--
Antonio Donatiello

sto elaborando qualcos'altro? Secondo me, no.
Secondo me, sě. Se sto facendo una lunga operazione quanto meno devo
permettere di annullarla. Come dici tu dopo, sta al programmatore
disattivare quello che non puň essere toccato.
Domenico

...

Non so... i messaggi WM_*** vengono mandati da Windows alle finestre
dell'applicazione VB... e VB non li processa (perche' e' "impastato" a fare
altro).
In effetti le finestre delle altre applicazioni funzionano bene (fanno il
repaint etc...), almeno credo.
Quindi il problema dovrebbe essere (ancora una volta) di VB.
--
Roal Zanazzi
z...@iol.it


Allora confermi la mia tesi: 
i programmi VB sono localmente non pre-hemptive  , cioe' e' il gestore
degli eventi degli oggetti del VB che non e' in grado , o meglio e'
stato progettato cosi per evitare una marea di casini e nel campo del
multitasking i casini ci sono e sono grossi, di interrompere una
subroutine per attivare un nuovo evento.
Daltro canto il problema in generale non e' significativo in quanto VB
ci fornisce la 'DoEvents' , da usarsi con parsimonia per forzare lo
scheduling degli eventi qualora la subroutine bloccasse per troppo tempo
questo.
Marco

Infatti se ne hai bisogno basta che chiami la DoEvents.
In C ad esempio avresti lo stesso problema e dovresti comunque chiamare la
GetMessage().
Ciao.
--
Antonio Donatiello



tutto cio' che l'utente non deve toccare.
Io uso una soluzione piuttosto semplice da realizzare:
il loop lo faccio eseguire all'interno di una piccola 
form Modal, dotata di Progress Bar e tasto di Cancel,
ovviamente introducendo nel loop una DoEvents.
L'unico oggetto attivo dell'applicazione e' il tasto
suddetto; l'evento Click si inserisce alla chiamata
della DoEvents, e posso gestirlo magari dopo aver
emesso un MsgBox di conferma.
-----------------------------------------------
Louis Cretier - 
http://www.show.it/lcretier.htm
-----------------------------------------------
"Beato chi nulla si aspetta / perche' non rimarra' deluso"
(Lettera di San Paolo ai Correntisti)

tutto cio' che l'utente non deve toccare.
Quindi il DoEvents agisce come la chiamata dell'API GetMessage() in C (solo
che ad un livello piu' alto).
A questo punto, continuo a domandarmi perche' diavolo M$ ne sconsigli
l'utilizzo!
--
Roal Zanazzi
z...@iol.it

questo.
Esatto, il problema (che ha creato questo thread di messaggi) e' che, a
quanto pare, Microsoft CONSIGLIA di NON usare DoEvents!!!
--
Roal Zanazzi
z...@iol.it

Se ti riferisci al fatto che nell'help c'e' scritto di usarla con cautela
sono d'accordo perche' dice appunto di evitare che l'utente possa interagire
con il programma e chiamare nuovamente la funzione che aveva chiamato la
DoEvents.
Sull'help dice che il risultato sarebbe imprevedibile (bisognerebbe sapere
come e' implementata la DoEvents) ma comunque credo che generalmente non sia
auspicabile che la stessa funzione in cui sono fermo venga richiamata
nuovamente e quindi sono comunque costretto ad attrezzarmi per fare in modo
che questo non accada.
Ciao
Antonio Donatiello

l'utilizzo!
In precedenza i programmatori VB utilizzavano DoEvents per permettere a
Windows di fare multitasking. Cioč se avevo un loop lungo non si
aggiornavano nemmeno le applicazioni di background. Ora questo non succede
piů, perché il multitasking di Win32 č piů avanzato, e quindi quest'uso di
doevents č sconsigliato. Naturalmente, all'interno della tua applicazione
tutto rimane come prima e se vuoi ricevere i messaggi devi fare doevents.
Ciao,
Domenico

 --
Azzardo:
perche' potenzialmente si possono fare delle cose distruttive tipo
togliere sotto il naso della routine sospesa controlli che sta usando o
modificando proprieta' critiche, perche' magari nell'ottica di un
linguaggio event-driven le routine di risposta agli eventi dovrebbero
essere considerate atomiche ( anche se a volte col VB ci mettono minuti
o peggio ), perche solo in alcuni casi e' l'unica soluzione.
Marco

 --
Semplicemente perchè DoEvents in un ciclo ciuccia minimo 50 millisecondi per
volta, e vb non ne ha proprio bisogno.
E comunque può essere complicato trovare errori in fase di debug se c'è lui
di mezzo.

di mezzo.
Ti assicuro che ci sono casi in cui avere un DoEvents ti salva ANCHE in fase
di debug (per lo meno ti permette di "entrare" in fase di debug... metti il
caso che hai un bel ciclo e, per una distrazione hai sbagliato ad impostare
la condizione di uscita... con un DoEvents nel ciclo hai ancora la
possibilita' di mettere in pausa e poi continuare passo-passo, senza... sei
come minimo costretto a killare VB)
Comunque, a prescindere dalle potenzialita' dannose di DoEvents, se esiste
questa funzione un motivo c'e' e non credo che sia stata fatta per caso.
Il problema nato in questo thread e' che qualcuno (di cui non ricordo il
nome) ha chiesto il motivo per cui M$ sconsiglia l'uso di DoEvents.
L'affermazione non mi risultava nuova, per cui mi sono aggregato alla
domanda perche' voglio sapere se veramente (e per quali motivi, oltre a
quelli che si conoscono gia') M$ sconsiglia l'uso di DoEvents.
Riporto quanto dice l'help in linea di VB a proposito di DoEvents, che
conferma i lati positivi del suo utilizzo (NON smodato):
"La funzione DoEvents è particolarmente utile per semplici operazioni come
consentire all'utente di annullare un processo dopo averlo avviato, ad
esempio la ricerca di un file."
Questa e' l'unica controindicazione dell'uso di DoEvents riportata
nell'help:
"Attenzione   Tutte le volte che si trasferisce temporaneamente il controllo
al processore all'interno di una routine di eventi, verificare che la
routine non venga di nuovo eseguita da un'altra sezione del codice prima che
termini la prima chiamata. Potrebbero verificarsi, infatti, risultati
imprevedibili. Non utilizzare inoltre DoEvents se, durante il periodo di
tempo in cui il controllo è stato passato, è possibile che altre
applicazioni interagiscano con la routine con effetti non prevedibili."
Ma non riesco a trovare un punto dove venga "sconsigliato" l'uso di


DoEvents!
Infatti.
Scusate se mi intrometto. 
Seguivo la discussione dall'esterno, perche' l'argomento mi interessa,
e cercavo di capire perche' non usare DoEvents.
Finora pero' sembra evidente che tutti lo usiamo e continueremo ad
usarlo, perche' funziona benissimo,  perche' a volte e' l'unico
strumento che rende possibile alcune operazioni, quindi ... usiamolo!
O meglio usiamolo con attenzione, dopotutto e' questo quello che dice
mamma microsoft.
Dopotutto la mamma dice anche di stare attenti all'uso dei Goto, pero'
io sono convinto che tutti lo usano, perche' a volte e' la soluzione
migliore per il rapporto qualita'-tempi di lavoro!!
Federico
fluc...@tin.it


ERESIA!!!!!!!!!!
VADE RETRO GOTO!!!!!!!!
Nel 90% delle volte in cui viene utilizzato il GOTO, portando come
giustificazione la maggiore velocita', il vero motivo e' una strutturazione
errata del codice, o un'incapacita' di modificare il flusso delle istruzioni
utilizzando i loop, while etc...
Il GOTO e' quasi sempre solo una scappatoia e SEMPRE porta a conseguenze
inimmaginabili, bachi difficili da trovare e lunghi (in termine di tempo) da
correggere.
--
Roal Zanazzi
z...@iol.it



Premessa:
Mi dispiace aver portato la discussione sul GOTO, qui si discuteva di
DoEvents.
In risposta a Roal:
Chiaramente non sono daccordo con te!
O meglio, non sono pienamente daccordo, nel senso che non puoi dire a
priori  che chi usa il GOTO e' un incapace.
Ritengo, come te,  che un buon programmatore deve saper strutturare il
flusso senza la 'scappatoia' dei GOTO, ma un buon programmatore deve
anche saper usare il GOTO e saper valutare i pro e i contro del suo
utilizzo.
Quindi se un programmatore usa il Goto in una determinata circostanza
(ma non ne abusa), non gli dico che e' un incapace, ma gli chiedo,
eventualmente, perche' in quel caso ha deciso cosi'.
Federico
fluc...@tin.it

eventualmente, perche' in quel caso ha deciso cosi'.
Se lui mi risponde con un confronto di prestazioni tra la soluzione col GOTO
e altre con costrutti strutturati (che, evidentemente ha provato e
confrontato) e mi dice che e' meglio ottimizzato con il GOTO, allora e' un
buon programmatore che rientra nel 10% dei casi... altrimenti e' nel 90% dei
casi e quel GOTO si puo' quasi sicuramente sostituire con una migliore
strutturazione del codice.
Come vedi, non penso a priori che chi usa i GOTO lo fa perche' non e' un
buon programmatore, ma alla fine salta fuori che nel 90% dei casi e' cosi'
:-(
--
Roal Zanazzi
z...@iol.it


OK!! Ora siamo daccordo  :-)
Scusami se mi sono un po' alterato, ma il fatto e' che avevo appena
terminato una discussione in un altro NG sull'uso del GOTO e c'era chi
affermava che usare GOTO e' sempre un errore di programmazione e via
discorrendo altre amenita'.
Quindi la mia e' stata una reazione a caldo. Scusami di nuovo.
Comunque io uso il Goto (in VB) in uno/due casi particolari e
continuero' a farlo fino a quando qualcuno non mi dimostrera' un
metodo alternativo piu' semplice e veloce.
Federico
fluc...@tin.it

 metodo alternativo piu' semplice e veloce.
Uno dei miei tipici casi dove uso goto e' questo:
(La funzione la scrivo in C inquanto e' un classico caso da C (raramente,
programmando in VB, mi capita di dover liberare risorse in modo pulito, se
non con l'apertura di N recordset) )
BOOL Funzione( void )
{
	BOOL	EsitoFunzione;
	FILE	*pFile1,*pFile2;
	char	*pBuffer1, *pBuffer2;
 
	EsitoFunzione = FALSE;
	pFile1 = pFile2 = NULL;
	pBuffer1 = pBuffer2 = NULL;
 
	pFile1 = fopen( "File1.xyz", "rb+" );
	if( !pFile1 ) goto Errore;
	pFile2 = fopen( "File2.xyz", "wb+" );
	if( !pFile2 ) goto Errore;
	pBuffer1 = malloc( 32768 );
	if( !pBuffer1 ) goto Errore;
	pBuffer2 = malloc( 32768 );
	if( !pBuffer2 ) goto Errore;
 
	....
	.....
	..
	EsitoFunzione = TRUE;
Errore:
	if( pBuffer2 ) free( pBuffer2 );
	if( pBuffer1 ) free( pBuffer1 );
	if( pFile2 ) fclose( pFile2 );
	if( pFile1 ) fclose( pFile1 );
	return( EsitoFunzione );
}
Un'altro caso che mi e' capitato in C (per DOS):
for( ; ; )
{
	Esito = InputUtente( .... );
	if( Esito==123) {
		int	Tasto;
		printf("Si desidera confermare\nPremi (S/N)\n");
		LoopTasto:
		Tasto = getch();
		if( Tasto=='S' || Tasto=='s') break;
		if( Tasto!='N' && Tasto!='n' ) goto LoopTasto;
	}
	// errore ripeto l'imput
}
In questo ultimo caso, o faccio "goto" o devo aggiungere un'ulteriore
controllo per uscire dal for(;;) primcipale.
Tutta roba che comunque non ha senso col VB. Usare i "goto" in VB vuol dire
che si sta lavorando in modo non consueto al VB stesso (allocando risorse
(API) ).

Ettore Maronese ha scritto nel messaggio
<01bdff89$dbfc7640$LocalHost@p266>...

scusa, non me ne intendo molto di C, ma nel caso qui sopra non potevi usare
(come sarebbe piů corretto) un ciclo del tipo:
for( ; ; )
{
 Esito = InputUtente( .... );
 if( Esito==123) {
 int Tasto;
 printf("Si desidera confermare\nPremi (S/N)\n");
 do
{
 Tasto = getch();
 if( Tasto=='S' || Tasto=='s') break;
 } while ( Tasto!='N' && Tasto!='n' );
 }
 // errore ripeto l'imput
}
se sě (in VB č cosě)  anche qui si poteva evitare il goto e il codice č piů
lineare (forse perň ho sbagliato ad interpretare!).
Nel caso della gestione degli errori invece il goto č inevitabile (in VB, in
C non esisteve il costrutto try-except/ try-finally?)

controllo per uscire dal for(;;) primcipale.
Questo potrebbe essere riscritto cosě (anche se piů lungo):
BOOL esci = 0;
do {
 Esito = InputUtente( .... );
 if( Esito==123) {
  int Tasto;
  printf("Si desidera confermare\nPremi (S/N)\n");
  do  {
    Tasto = getch();
    if( Tasto=='S' || Tasto=='s') { esci=1; break;}
   } while ( Tasto!='N' && Tasto!='n' );
 }
} while (!esci)
In questo caso, come dici tu, inserirei un'altra variabile di controllo, che
non credo penalizzi le prestazioni in quanto si č in attesa dell'input di un
utente. Personalmente preferisco la tua soluzione, perchč č piů "snella".
Lo so che questi sono casi particolari e ci sono situazioni in cui il goto č
quasi indispensabile, pena contorti statement procedurali, ma stavolta
c'erano dei workaround abbastanza efficaci.
P.S. ma non siamo un po' OT ? :-)
--
Ciao, AntoGal
*************************************************
Home Page (area programmatori di VolFtp)
http://volftp.tin.it/italiani/galletta/
per scaricare un gioco di DAMA ITALIANA
*************************************************

 C non esisteve il costrutto try-except/ try-finally?)
Il tuo break esce dal primo do while, ma non dal for(;;).
Col tuo codice non esce MAI dai for(;;).
(chiedo ancora scusa se ho fatto gli esempi in C anziche' in VB)
-- 
Ciao
By -MES-   Maronese Ettore
http:\\
ilmes.freeweb.org
(con OCX per stampare i recordset)
Sito Comune di programmatori Visual Basic
http://members.xoom.com/it_lang_vb

 } while (!esci)
Verissimo, e MOLTO spesso faccio cosi' proprio perche' odio usare i 'goto'.
Ma ci sono volte in cui mi accorgo che per evitare un 'goto' mi ritrovo a
scrivere codice meno leggibile rispetto all'uso di un 'goto' stesso.
Insomma...  Ma se la pensiamo tutti allo stesso modo, perche' continuiamo
ad allungare questo thread?....  :-))
(Rinnovo le mie scuse per aver fatto esempi di codice in C anziche' in VB)
Salutoni a tutti

A questo punto sarebbe necessario un'altro NG:
it.comp.lang.visual-basic.doevents
:-)
(Scusate il disturbo)
Ciao