none
Backgroundworker RRS feed

  • Domanda

  • Premetto che la cosa che tento di fare è un po cervellotica ma non ho trovato un modo migliore x farla

    Avendo un codice del genere

     For i = 0 To Connessioni - 1
    Dim a(5)
    a(0) = Parametri(4 * i + 1)
    a(1) = Parametri(4 * i + 2)
    a(2) = Parametri(4 * i + 3)
    a(3) = Parametri(4 * i + 4)
    a(4) = Parametri(0)
    bwDDns = New BackgroundWorker
    AddHandler bwDDns.DoWork, AddressOf bwDDns_DoWork
    AddHandler bwDDns.RunWorkerCompleted, AddressOf bwDDns_RunWorkerCompleted
    bwDDns.RunWorkerAsync(a)
    If bwConnessioni.CancellationPending Then
    Exit For
    End If
    Next


    Private Sub bwDDns_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs)
    Dim a = e.Argument
    Dim Connetti As New DDns(a(0), a(1), a(2), a(3), a(4))
    Dim R_T As String
    Do
    R_T = Connetti.Risultato(ip)
    If bwDDns.CancellationPending Then
    Exit Do
    End If
    Thread.Sleep(1000)
    Loop While R_T Is Nothing
    NT += a(2) + vbCrLf
    If R_T <> "" Then
    Inoltro(R_T)
    End If
    End Sub

    Essendo che vengono lanciati vari backgroundworker dal ciclo for, esiste un modo x gestire i vari processi e nel caso terminarlo nel caso non vada a buon fine? x essere + chiaro se ne lancio 5 di bwDDns e vorrei terminare il terzo lanciato? nel caso esiste un'altra soluzione?
    grazie anticipatamente x la risposta

     

    lunedì 5 dicembre 2011 13:43

Risposte

  • Devi scrivere qualcosa del genere:

         ' Crea un array per contenere tutti i BackgroundWorker.
            Dim bwDDns(5) As BackgroundWorker
    
            For i As Integer = 0 To 4
                '...
                'Crea un nuovo BackgroundWorker all'interno dell'array e lo esegue.
                bwDDns(i) = New BackgroundWorker()
                bwDDns(i).RunWorkerAsync(a)
                '... 
            Next
    

    In questo modo, definisci bwDDns come un array che contiene 5 BackgroundWorker. Se, ad esempio, vuoi terminare il terzo (quindi, nell'array con indice 2), ti basta scrivere: 

    bwDDns(2).CancelAsync()
    

     


    Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom

    lunedì 5 dicembre 2011 14:35

Tutte le risposte

  • Certo, quello che devi fare è tenere un riferimento ai vari BackgroundWorker che crei (ad esempio all'interno di un array), quindi richiamare il metodo CancelAsync (http://msdn.microsoft.com/it-it/library/system.componentmodel.backgroundworker.cancelasync.aspx) sul worker che vuoi terminare.


    Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom
    lunedì 5 dicembre 2011 14:06
  • non credo di aver capito

    se il ciclo for fosse

    for i=0 to 4

    ...

    bwDDns.RunWorkerAsync(a)

    ...

    i+=1

    next

    restando invariato il resto del codice in questo caso partono contemporaneamente (o quasi) cinque thread di nome bwDDns, come faccio a chiamarli? se ne fosse uno basterebbe dirgli bwDDns.cancelasync() avendo impostato all'interno del thread il cancelpending, ma essendone + di 1 e non è detto che ce ne sia solo 1 in tilt, ma anche 2 o + (nel caso di interruzione del servizio), come faccio ad identificarli e nel caso a terminarli? se lancio bwDDns.cancelasync() non termina solo l'ultimo?

    Grazie comunque x la risposta precedente e chiedo scusa se forse non riesco a comprendere la cosa, forse sono un po all'inizio nell uso dei thread

    lunedì 5 dicembre 2011 14:20
  • Devi scrivere qualcosa del genere:

         ' Crea un array per contenere tutti i BackgroundWorker.
            Dim bwDDns(5) As BackgroundWorker
    
            For i As Integer = 0 To 4
                '...
                'Crea un nuovo BackgroundWorker all'interno dell'array e lo esegue.
                bwDDns(i) = New BackgroundWorker()
                bwDDns(i).RunWorkerAsync(a)
                '... 
            Next
    

    In questo modo, definisci bwDDns come un array che contiene 5 BackgroundWorker. Se, ad esempio, vuoi terminare il terzo (quindi, nell'array con indice 2), ti basta scrivere: 

    bwDDns(2).CancelAsync()
    

     


    Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom

    lunedì 5 dicembre 2011 14:35
  • Grazie mille x la risposta, ignoravo che si potessero creare un array di backgrounworker (anche se a rigor di logica sono comunque classi cvhe si comportano come tutti gli altri ehehe)

    Gentilissimo

    lunedì 5 dicembre 2011 14:50
  • E' un piacere esserti stato d'aiuto!

    Ti chiedo gentilmente di marcare il mio post come risposta :-)

    Grazie a te!


    Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom
    lunedì 5 dicembre 2011 15:49
  • Fatto, visto la tua gentilezza scusa se ne approfitto, visto che con questi backgrounworker c'è semnpre un problema di troppo ^^, quando lancio il programma e si inchioda non mi da la possibilità di capire dove si è inchiodato, non restituendo l'errore all'interno dei thread, mi spiego meglio se copio il blocco di codice e lo faccio eseguire come semplice codice x poterlo veirficare, tutto funge se lo faccio procedere passo passo, tutto funge, mentre se lo lancio senza interruzioni o senza il passo passo si inchioda, presumo x qualche problema di esecuzioni contemporanee, o di altra natura, e qui la mia domanda, esiste un opzione da flaggare o un comando da includere nel codice x far fermare il debug dell'applicazione in caso di restituzione di errore all'interno di un thread e non semplicemente bloccarsi e non andare avanti? mi spiego meglio se nel codice di un backgroundworker c'è un errore grossolano invece di stopparsi il debug e dare l'errore si blocca l'esecuzine del thread no restituendo nessun errore e non dando nessun break all'esecuzione del programma, se metto in pausa il debub mi dice Origine non disponibile e sotto nessuna soluzione (da premettere che alcune operazioni sono all'interno di dll separate ma correttamente integrate)
    martedì 6 dicembre 2011 18:50
  • Puoi usare la finestra di dialogo Exceptions, raggiungibile dal menu Debug, oppure con la combinazione CTRL+D, E, per decidere quali sono le eccezioni che devono bloccare l'esecuzione e restituire l'errore. Di norma, la colonna User-unhandled in corrispondenza della voce Common Language Runtime Exceptions è spuntata (provvedi se non fosse così).

    Questo, però, garantisce solo che l'esecuzione si interrompa nel caso di eccezioni non gestite. I motivi per cui un thread in background si blocca possono essere molteplici. Innanzi tutto, le cosiddette corse critiche, ovvero un thread usa la risorsa A ed in attesa della risorsa B, e nello stesso tempo il thread che possiede la risorsa B richiede la A: in una situazione del genere, si verifica una situazione di stallo, ovvero ogni thread ha bisogno di una risorsa posseduta da un altro. Identificare problemi di questo tipo, può non essere facile.

    Ti consiglio di provare a seminare un po' di istruzioni Debug.Write nel tuo codice, cosicché consultando la finestra di Ouput puoi capire esattamente dove si trova il flusso di esecuzione del programma.


    Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom
    martedì 6 dicembre 2011 20:26
  • Grazie mille provvederò ad informarmi su tali comandi e tali funzioni gentilissimo
    mercoledì 7 dicembre 2011 14:20
  • OK, fammi sapere gli sviluppi della situazione.

    A presto!


    Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom
    mercoledì 7 dicembre 2011 14:32
  • sembra stranissimo ma il problema era bwDDns messo direttamente in fase di designer, avevo modificato in questo modo x ovviare all'inserimento di queste righe nel codice:

    AddHandler bwDDns.DoWork, AddressOf bwDDns_DoWork
    AddHandler bwDDns.RunWorkerCompleted, AddressOf bwDDns_RunWorkerCompleted

     

    ma no so come mai in presenza del controllo backgroundworker in fase design (forse dal momento che usavo bwDDns = new backgroundworker) si inchiodava se lanciato a briglia sciolta, invece se lo lanciavo ocn l'f8, passo passo andava tutto a buon fine.

    avevo fatto questa modifica x ovviare un messaggio di errore nel form closed, quando scrivevo

    if bwDDns.isbusy

    ...

    endi if

    mi diceva che l'oggetto non esisteva

    allora ho semplicemente aggiunto una dichiarazione

    dim bwDDns as new backgroundworker al posto di dim bwDDns as backgroundworker e non si inchioda +, comunque vedrò di inserire i controlli debug.write nelle varie dll cosi da avere un report in caso di errori, userà il buon vecchio msdn x informarmi sul suo funzionamento di nuovo grazie

    mercoledì 7 dicembre 2011 15:14