Newsgroup: it.comp.lang.visual-basic
Titolo: [.net] Problemi di Threading

Ciao a tutti
Sto realizzando un'applicazione che scarica dal web varie immagini
(da webcam) e le salva su HD. Per farlo avevo pensato di utilizzare i
Thread in modo da poter gestire più download contemporaneamente senza
che tutto si inchiodi se per caso un'immagine non si riesce a
scaricare.
Ho costruito una classe apposita che contiene tutte le informazioni
delle telecamere e che, tramite un timer, fa partire il download
dell'immagine.
questo è il codice del tick del timer
Private Sub TimerEventProcessor(ByVal myObject As Object, ByVal
myEventArgs As EventArgs)
        Dim i As Integer
        For i = 0 To mtThread.GetUpperBound(0)
            If mtThread(i).ThreadState =
Threading.ThreadState.Unstarted Or mtThread(i).ThreadState =
Threading.ThreadState.Stopped Then
                ' gestione thread in modo da non far partire
GetPicture piu volte per la stessa telecamera
                mtThread(i) = Nothing
                mtThread(i) = New System.Threading.Thread(AddressOf
getPicture)
                mtThread(i).Start(vCamData(i))
                RaiseEvent DownloadStart(vCamData(i).nome & " -
Download Iniziato", i)
            Else
                'txt.Text = "T1 IN ATTESA"
                RaiseEvent DownloadInProgress(vCamData(i).nome & " -
Download in corso", i)
            End If
        Next
End Sub
Ho gestito le cose in modo da non far partire un nuovo download per
una webcam quando il precedente stà ancora lavorando.
Tutto sembra andare per il meglio se non che quando lascio acceso il
programma per una decina di minuti tutto si blocca...
Analizzando il processo ho notato un leggero aumento nel tempo della
memoria utilizzata.
Qualcuno ha già avuto problemi del genere o ha qualche consiglio da
darmi?
Grazie
   Marco


Ah dimenticavo di specificare, sto usando 
vb.net
 2005 con windows xp
pro sp2
Grazie ancora
  Marco

e "getPicture" che fa?
Non č che il problema sia li dentro, magari vai a modificare dei dati 
condivisi.
Perchč non incapsuli per bene tutti i dati che servono in un oggetto piů 
complesso.
Ti crei il tuo bel arraylist di oggetti MyWebcam che incapsulano a loro 
volta il rispettivo tread di scaricamento.
Esponi poi dei metodi per stabilire se la webcam sta scaricando e quindi nel 
controllo timer la attivi se č in standby, altrimenti passi alla successiva.
Inoltre ti consiglio di bloccare il timer quando parte il suo evento e poi 
lo riattivi all'uscita, altrimenti se l'intervallo č troppo breve, rispetto 
al tempo richiesto all'esecuzione delle istruzioni, magari ti parte un 
secondo evento. 

 secondo evento.
Questa è getpicture, non fa altro che scaricare da web l'immagine
Private Sub getPicture(ByVal vData As Object)
        ' funzione per il download dell'immagine
        Dim m1(-1) As Byte
        Dim dbyte As New System.Net.WebClient
        Dim memstream As New System.IO.MemoryStream
        Dim imgScaricata As System.Drawing.Image
        Try
            m1 = dbyte.DownloadData(vData.url)
            memstream.Write(m1, 0, m1.Length)
            imgScaricata = System.Drawing.Image.FromStream(memstream)
            imgScaricata.Save(My.Application.Info.DirectoryPath & "/"
& vData.path & Format(Now, "yyMMddhhmmss") & ".jpg",
System.Drawing.Imaging.ImageFormat.Jpeg)
            ' distruzione oggetti non più necessari
            imgScaricata.Dispose()
            memstream.Dispose()
            dbyte.Dispose()
            memstream = Nothing
            imgScaricata = Nothing
            dbyte = Nothing
            m1 = Nothing
            RaiseEvent DownloadEnd("DOWNLOAD COMPLETATO", vData.index)
        Catch
            ' questa parte da dei problemi quando si scatena l'evento,
nella funzione che intercetta l'evento non riesco a fare operazioni di
sorta per loggare/mostrare a video il messaggio di errore (da vedere
meglio)
            RaiseEvent DownloadError(vData.nome & "ERRORE DI DOWNLOAD
" & Err.Description, vData.index)
        End Try
    End Sub
vData che viene utilizzato in questa funzione è una classettina di
appoggio che contiene i vari dati delle telecomere, path descrizione e
un index per poi ritrovarla senza problemi nell'array dei thread.
forse prima non l'avevo specificato ma ho un array di thread,
assegnato ogni uno a una diversa telecamera e questo viene
riutilizzato di volta in volta per il download della nuova immagine.
Il timer ho dimenticato di disabilitarlo... di solito lo faccio,
grazie!

Devi stare attento che in Vb 2005 i tread sono molto cambiati rispetto alla 
precedente versione.
In particolare se in un form gestisci degli eventi che sono scatenati da 
un'altro tread, che è appunto il caso tuo, vengono sollevate delle 
eccezioni.
In pratica i controlli di un form possono essere modificati dal tread stesso 
e non da altri, a meno che non lo fai fare ad una funzione delegata e quindi 
sei tu a intercettare e gestire la chiamata proveniente da un tread esterno.
Questa caratteristica è stata introdotta dalla MS per evitare (giustamente) 
che i controlli in un form assumano uno stato incoerente rispetto ai dati 
che essi visualizzano.
Se vuoi puoi però disattivare tale caratteristica basta che nel load del 
form imposti
CheckForIllegalCrossThreadCalls = False
Questo dovrebbe risolvere il problema che hai messo nel commento del codice 
nel blocco Try, ovvero che non riesci a monitorare gli eventi.
Per il resto non ho notato cose particolari, ma non ho neanche approfondito 
più di tanto.
Lavorare con i tread purtroppo non è molto semplice, per questo ti consiglio 
di riformulare il tutto in modo un po più strutturato incapsulando per bene 
i dati.
A dire il vero io i tread li uso poco, non per pigrizia, ma perchè in 
effetti mi servono poco se non per lanciare procedure onerose che altrimenti 
bloccherebbero il pc.
Nel caso tuo l'applicazione è proprio di tipo multi tread per asua natura.
Mi sembra che sul libro nuovo di Balena sul vb 2005 parli in maniera 
piuttosto estesa dei tread.
ciao 

Grazie per la risposta così dettagliata, il Balena celho a casa,
stasera provo a dare un occhio meglio.
Appena riesco a strutturare meglio il tutto vi faccio sapere come
va' :) speriamo bene