Newsgroup: it.comp.lang.visual-basic
Titolo: [?] Lanciare una sub asincrona

E' possibile lanciare una sub asincrona?
In pratica vorrei fare quello che fa un command button quando viene
cliccato:  la sub associata al click gira indipendentemente dal resto
dell'applicazione.
Il tutto possibilmente senza usare i thread che, a quanto leggo in giro, non
funzionano a dovere con VB6.
termoPilucco

 funzionano a dovere con VB6.
da profano della materia farei un esegubile "esterno". certo che, cosě,
faresti molta fatica a controllare il processo.
secondo tentativo: una classe che informa il chiamante tramite eventi, e che
fa un uso intensivo del "doevents" per permettere al chiamante di continuare
a funzionare.
-- 
Salutoni
Sergio
per rispondere... togli il group dall'indirizzo

 a funzionare.
Ho trovato qualcosa del genere qui:
http://support.microsoft.com/default.aspx?scid=kb;en-us;176951
Lo sto provando, ma sembra interessante perchč provvede anche ad installare
un semplice meccanismo di callback.
termoPilucco

 > sai che questa non l'ho capita?
Ecco, mi è venuto in mente un esempio semplice:
Ha presente il controllo MSXML?
Ha una proprietà async.
Se settata a true, quando fai una richiesta ad un server il controllo del
"program counter" torna subito al chiamante, ma la richesta XML prosegue per
i fatti suoi magari per interi minuti.
Vorrei poter fare la stessa cosa, ma con una sub scritta da me.
termoPilucco

 continuare  a funzionare.
Ecco, qui ho trovato un esempio per .NET che sembra (dico sembra, perchè non
ho .NET sotto mano) fare quello che voglio:
Sub CreateThread()
  Dim b As BackGroundTask
  Dim t As Thread
  Set b = New BackGroundTask()
  Set t = New Thread(New ThreadStart(AddressOf bTask))
End Sub
Class BackGroundTask
    Sub Task
    . . .
    End Sub
End Class
Non esiste un equivalente per VB6 (a questo punto usando i thread)
funzionante?
termoPilucco

 comportarsi come thread separati.
A me non pare...
Un DoEvents dice (in pratica) di elaborare gli eventi in coda, ma, come
avviene nell'esempio che segue, l'evento in corso viene sospeso e ripreso
alla fine. Non non per altre situazioni, ma ... mi torna:
Un form con due bottoni e due label.
Avvia, clicca sul primo bottone e dopo qualche istante, sul secondo.
Noterai che il primo si ferma, per riprendere solo quando il secondo ha
finito.
Puoi farlo piů volte (non troppe, altrimenti non smette piů), noterai che
gli eventi sono "stackati" e "de-stackati"
Private Sub Command1_Click()
    Call conta(Label1)
End Sub
Private Sub Command2_Click()
    Call conta(Label2)
End Sub
Sub conta(label As label)
    For x = 1 To 30000
        label.Caption = x
        label.Refresh
        DoEvents
    Next x
End Sub

 gli eventi sono "stackati" e "de-stackati"
Giā.
Il secondo click agisce come un interrupt.
termoPilucco

 funzionante?
No.
L'unica è demandare a un processo esterno, di cui però perderesti il 
controllo.
Ciao

 perderesti il  controllo.
Vabbč, non era cosě importante :)
termoPilucco

 separato.
No. Anche l'ActiveX separato si comporta come se la sub fosse in locale.
Rimangono solo i Thread... ho provato un bell'esempio ad hoc e, indovinate
un po', crasha che Bill la manda.
termoPilucco

 funzionano a dovere con VB6.
esatto.
Devi usare un EXE ActiveX, che esegua il codice in un processo separato.
Cerca su MSDN "Creating an ActiveX EXE Component" e "Asynchronous 
Notifications Using Events".
Ciao,
Moreno
Inviato da 
www.mynewsgate.net

 Notifications Using Events".
Sei sicuro?
Secondo me non funziona.
Una chiamata a un Ax-exe è pur sempre sincrona.
Ciao

Il 26/04/2004 16.24, termoPilucco scrisse:

Hai gia' visto l'esempio coffee sulla guida?
ciao
	maxx
-- 
NOSPAM: Rimuovere i trattini dallo username!
Cut hyphens from my username!

 ha scritto nel messaggio
news:c6l0el$d6ptg$3...@ID-184808.news.uni-berlin.de...

La chiamata è sincrona, ma non l'esecuzione del codice :)
ovvio che bisogna lavorare sugli eventi (o callback), perchè se mi faccio
ritornare il valore di una funzione, ovvio che il processo rimane sincrono.
Saluti

 Hai gia' visto l'esempio coffee sulla guida?
Usti... avevo il sorgente sul mio PC bello pronto.
E' un po' incasinato ma sembra fare tante cosette interessanti.
Però mi sa che aspetto di migrare a .NET per fare queste cose :)
grazie,
termoPilucco

 ritornare il valore di una funzione, ovvio che il processo rimane sincrono.
No, aspetta.
Se una chiamata è sincrona non è asincrona :)
Che differenza c'è tra chiamare una sub e una funzione?
La si chiama e VB aspetta che questa finisca prima di continuare.
Che poi all'interno tu puoi scatenare eventi allora lo fai tutti i 
giorni con qualsiasi classe che espone eventi.
Ciao

 giorni con qualsiasi classe che espone eventi.
sì, ma sempre in process.


 callack ed eventi di notifica.
Mah... ho appena fatto un DCOM e non mi pare si comporti così.
Tu vuoi dire che se io faccio
Debug.Print Now
Call MyActiveXExe.SubCheImpiega10Sec()
Debug.Print Now
tra i due Now non passano 10 secondi?
Non ci credo :)
O meglio, faccio fatica a crederci.
Ciao

 Debug.Print Now
Scusa ma allora che differenza c'č tra un componente inprocess ed out of
process .. solo il modello di threading ?
Saluti

Il 27/04/2004 14.25, Zanna scrisse:

Se MyActiveXexe e' out-of-process allora la chiamata e' asincrona e non 
passano 10 secondi.


 process .. solo il modello di threading ?
Cosa c'entra il modello di threading con il fatto di essere in o out of 
process?
Ciao

 passano 10 secondi.
Ho provato e non è così.
Le chiamate sono sincrone.
Se c'è qualche settaggio strano da impostare sull'ax-exe io non lo conosco.
Ciao

Il 27/04/2004 14.55, Zanna scrisse:

E' un po' che non metto mano al codice in questione, ma ricordo che 
avevo seguito passo passo l'esempio coffee e le chiamate erano asincrone.
Se guardi quell'esempio ci sono tutte le spiegazioni che servono.


 process .. solo il modello di threading ?
Non sono stato spiegato :)
Dicevo .. ci sarà pure qualche differenza "funzionale" tra DLL e EXE activex
? (una di queste è appunto il modello di threading ... un'altra differenza è
che una crea file .dll e l'altra crea file .exe:)
Saluti

 No. Anche l'ActiveX separato si comporta come se la sub fosse in locale.
un tricketto è quello di chiamare, sul server exe, una Sub che abilita un
timer (intervall a quanto ti pare, pure 1 millisecondo) ed esce.
il client continua ad andare per i fatti suoi ed il server comincia
l'elaborazione allo scadere del timer
-- 
Ciao, Silv:o)

 file .exe:)
Un'altra differenza è che ad una dll ACtivex si può passare un controllo
(label, per esempio) e la DLL può leggere/scrivere sulle proprietà del
controllo, mentre con un exe ActiveX no (errori in fase di esecuzione).
Stavo giusto provando a prendere l'esempio di Lupo delle due label con due
contatori, ma con l'exe Activex non sono riuscito a farlo funzionare. Mi sa
che mi dovrò leggere un tutorial :/
termoPilucco.
Dim clsAcqua As New acqua
If TypeOf clsAcqua Is acqua Then
    MsgBox "La classe è acqua"
End If

 l'elaborazione allo scadere del timer
Si avevo pensato a questo (leggendo del codice di MSDN, mica da solo)...
Prima o poi approfondisco.
grazie,
termoPilucco

 O meglio, faccio fatica a crederci.
Allora, ho ripreso anch'io in mano il discorso ed ho fatto alcune prove.
In effetti abbiamo ragione tutti (il che sulla base del risultato equivale a 
dire che tutti abbiam commesso degli errori, ma almeno è più dignitoso :-))), 
ossia:
-) è vero che un exe activex viene eseguito in un nuovo processo (e fin qui 
eravam d'accordo tutti)
-) è vero che può essere usato per l'esecuzione di procedure asyncrone
-) non è vero che basta invocare un metodo della classe di tale componente: COM 
comunque resta sempre sincrono e non ritorna il controllo al chiamante sino 
alla completa esecuzione del codice di una procedura, indipendentemente dal 
threading model (che qualcuno ha citato, *).
Quindi per creare delle procedure asyncrone è comunque necessario utilizzare 
una timer procedure, anche in un componente out of process: la timer procedure 
viene avviata dal metodo invocato, quindi il controllo ritorna al client; allo 
scatenarsi del timer viene generato l'evento gestito dal client stesso (o 
invocata la callback, a seconda).
(*) per verificarlo basta impostare il threading model dell'activex a "thread 
per object" ed usare nel metodo invocato dal cliente l'api sleep: questa 
dovrebbe freezare solo il thread corrente (quindi quello della specifica 
istanza del componente), ma siccome COM attende comunque che la procedura 
termini (ed eventualmente ritorni un valore), anche il client resta in attesa.
Spero sia un po' più chiaro.


 Spero sia un po' più chiaro.
Bella lì :)
termoPilucco