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

Argomento scabroso.
Parliamo di un normale progetto Exe in VB6.
C'è l'evento A.
Questo scatena una sub A.
All'interno della Sub A, ho l'assoluta necessità di gestire eventuali 
ulteriori eventi.
Arriva l'evento B.
All'interno della sub A, c'è un doevents che consente a Windows di 
scatenare la sub B.
All'interno della sub B, per millemila motivi, devo restare in attesa 
di qualcosa, per cui avrei tempo e CPU per consentire alla sub A di 
completarsi. Ma finchè non completo la sub B, il controllo non torna 
mai alla sub A.
Anche se all'interno della sub B, inserisco millemila doEvents, in 
realtà non c'è nessun evento che mi richiami la sub A nel punto in cui 
era al momento del suo Doevents.
Lo so che VB6 non è gran che sul tema del multithreading, ma non è che 
qualcuno ha scoperto un trick per smanettare nello stack delle 
chiamate?
Alberto
-- 
Heinrich Zille: Ognuno crede che l'altro sia come se stesso, 
dimenticando che al mondo esistono anche delle persone oneste.

 chiamate?
Io no... (in verità su VS Magazine di maggio 2002 c'era un esempio di "stack 
walking" ;-))
Ma se anche lo conoscessi sarebbe un po' troppo macchinoso e pericoloso.
Infatti dovresti far saltare il flusso del programma alla sub A nel punto 
indicato sullo stack 2 o tre chiamate sopra, però ricordarti del punto in 
cui eri arrivato nella sub B... insomma un mezzo casino.
Per come la vedo io l'unico modo è cambiare la filosofia con cui la sub B 
attende quel qualcosa.
Invece di entrare in un loop con all'interno un doevents (come immagino tu 
abbia fatto), potresti attivare un timer che ad intervalli regolari effettua 
il controllo ed uscire dalla sub B, rientrando nella A, ovviamente.
Ciao
Raf

 mai alla sub A.
Mmm...no so se ho capito bene...
Io solitamente uso la MsgWaitForMultipleObjects, anzi, per dire la
verità una funzione wrapper (non creata da me).
Nella SubA metti un MsgWaitForMultipleObjects che attende l'Evento
hSbloccaA;
Nella SubB resti sempre in attesa con un altro
MsgWaitForMultipleObjects e poi setti l'evento: SetEvent hSbloccaA;
Ma, ripeto, sempre se ho capito..
Il wrapper che uso è il seguente:
' The MsgWaitObj function replaces Sleep,
' WaitForSingleObject, WaitForMultipleObjects functions.
' Unlike these functions, it
' doesn't block thread messages processing.
' Using instead Sleep:
'     MsgWaitObj dwMilliseconds
' Using instead WaitForSingleObject:
'     retval = MsgWaitObj(dwMilliseconds, hObj, 1&)
' Using instead WaitForMultipleObjects:
'     retval = MsgWaitObj(dwMilliseconds, hObj(0&), n),
'     where n - wait objects quantity,
'     hObj() - their handles array.
Public Function MsgWaitObj(Interval As Long, _
            Optional hObj As Long = 0&, _
            Optional nObj As Long = 0&) As Long
    Dim T As Long, T1 As Long
    If Interval <> INFINITE Then
        T = GetTickCount()
        On Error Resume Next
        T = T + Interval
        ' Overflow prevention
        If Err <> 0& Then
            If T > 0& Then
                T = ((T + &H80000000) _
                + Interval) + &H80000000
            Else
                T = ((T - &H80000000) _
                + Interval) - &H80000000
            End If
        End If
        On Error GoTo 0
        ' T contains now absolute time of the end of interval
    Else
        T1 = INFINITE
    End If
    Do
        If Interval <> INFINITE Then
            T1 = GetTickCount()
            On Error Resume Next
         T1 = T - T1
            ' Overflow prevention
            If Err <> 0& Then
                If T > 0& Then
                    T1 = ((T + &H80000000) _
                    - (T1 - &H80000000))
                Else
                    T1 = ((T - &H80000000) _
                    - (T1 + &H80000000))
                End If
            End If
            On Error GoTo 0
            ' T1 contains now the remaining interval part
            If IIf((T1 Xor Interval) > 0&, _
                T1 > Interval, T1 < 0&) Then
                ' Interval expired
                ' during DoEvents
                MsgWaitObj = STATUS_TIMEOUT
                Exit Function
            End If
        End If
        ' Wait for event, interval expiration
        ' or message appearance in thread queue
        MsgWaitObj = MsgWaitForMultipleObjects(nObj, _
                hObj, 0&, T1, QS_ALLINPUT)
        ' Let's message be processed
        DoEvents
        If MsgWaitObj <> nObj Then Exit Function
        ' It was message - continue to wait
    Loop
End Function
Bye,
Daniele.

 Mmm...no so se ho capito bene...
Grazie, avevi capito benissimo.
Terrò salvata questa soluzione, che sembra molto centrata sul mio 
problema.
In realtà sono nel frattempo riuscito a spezzettare ciò che avviene in 
sub A e in sub B in frammenti, ciascuno dei quali scatenabile con gli 
opportuni eventi. In questo modo, sono riuscito ad evitare loop e 
attese, in quanto i singoli frammenti vengono eseguiti e rilasciano il 
controllo al sistema finchè non arriva l'evento che avvia il frammento 
successivo.
Ciao e grazie a entrambi
Alberto
-- 
Friedrich Nietzsche: Un po' di salute ogni tanto è il miglior rimedio 
per l'ammalato.