[Vb.net 2010] Aiuto background worked

Sevenjeak

Utente Attivo
27 Nov 2012
81
2
8
36
sevenjeak.altervista.org
Premetto che non uso spesso il BackgroundWorked, ma sto provando, per un'altro mio programma, ad aggiornare, ogni secondo, la proprietà Text del form, con la data corrente, oltre a questo ho inserito alla chiusura del programma che: viene interrotto il lavoro in background e che lo stesso programma non viene chiuso ( solamente per ora ), il codice è questo:

Codice:
Private Sub mainForm_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        BackgroundWorker1.CancelAsync()
        e.Cancel = True
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        BackgroundWorker1.WorkerReportsProgress = True
        BackgroundWorker1.WorkerSupportsCancellation = True
        Dim i As Integer = 0

        While True
            System.Threading.Thread.Sleep(1)
            BackgroundWorker1.ReportProgress(i)

            If BackgroundWorker1.CancellationPending = True Then
                e.Cancel = True
            Else
                i += 1
            End If
        End While
    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        Me.Text = Now
    End Sub

Ora questo codice, mi deve visualizzare, nel titolo del form, l'ora in tempo reale, e fino qui tutto ok, ma, quando chiudo il form, il lavoro in background mi continua ( mi mostra sempre l'orario corrente, senza fermarsi ), sbaglio qualcosa io?
 
Prova a fare questo:

BackgroundWorker1.WorkerSupportsCancellation = true;
BackgroundWorker1.CancelAsync();
BackgroundWorker1.Dispose();
BackgroundWorker1= null;
 
Il WorkerSupportsCancellation = true; lo inserito nell'evento doWork(), cmq ho provato a scrivere cosi:

Codice:
BackgroundWorker1.CancelAsync()
        BackgroundWorker1.Dispose()
        BackgroundWorker1 = Nothing
        e.Cancel = True

Ma non funziona lo stesso, ora mi restituisce un NullReferenceException nell'evento doWork() nella linea, backgroundWorker1.reportProgress(i), credo che me lo faccia perché ho impostato a Nothing il backgroundWorker, mi restituisce questa eccezione: Object reference not set to an instance of an object.
 
E tu non puoi controllare che backgroundWorker1.reportProgress(i) sia diverso da null e in caso negativo non fare eseguire il codice?
 
Si, una soluzione potrebbe essere questa.

Ma perchè il programma non deve essere chiuso?
 
Non c'è nessun motivo, quell''istruzione, e.cancel = true, che ovviamente non permette la chiudere il programma, lo messa solamente per verificare che l'istruzione sopra, che fermano il lavoro in background, venissero eseguite correttamente, solo per quello non faccio chiudere il programma, solo per verificare questo, infatti una volta che riesco il programma lo faccio chiudere.

Ora sto provando a modificare il codice come hai detto te, ti farò sapere.
 
Scusate se uppo ma non posso editare il mio precedente messaggio, cmq ho provato a modificare il while cosi:

Codice:
while BackgroundWorker1.ReportProgress(i) = Nullable

Ma mi segna sia BackgroundWorker1.ReportProgress(i) che Nullable in rosso.

Per ora sto provando a cercare la soluzione su internet ma non saprei come fare.
 
In tutti gli esempi che troverai vedrai che viene indicato il metodo CancelAsync() per terminare l'elaborazione.

Quello che succede a te dipende probabilmente dall'operazione di annullamento della chiusura del form, cioè l'e.cancel = true annulla pure la terminazione del backgroundworker.

Pertanto chiudendo il form tutto dovrebbe funzionare.
 
Guardando su internet mi sono ricordato del metodo CancellationPending, che verifica se è stato chiamato il metodo di CancelAsyns(), il metodo e.cancel = true non centra niente, il quando fa riferimento all'evento di chiusura del form, infatti, modificando il codice cosi:

Codice:
    Private Sub mainForm_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        BackgroundWorker1.CancelAsync()
        e.Cancel = True
    End Sub

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim i As Integer = 0

        While BackgroundWorker1.CancellationPending <> True
            System.Threading.Thread.Sleep(1)

            BackgroundWorker1.ReportProgress(i)
            i += 1
        End While
    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        Me.Text = Now
    End Sub

Il codice funziona correttamente, ora posso anche togliere l'annullamento della chiusura, grazie per l'aiuto.
 
Io non ho detto che l' e.cancel = true c'entrasse direttamente con il backgroundworker, intendevo che annullando la chiusura del form alcune risorse potevano non essere rilasciate e dare problemi.

Se hai risolto così va bene, comunque anche controllare se BackgroundWorker1.ReportProgress(i) non ha valore nullo è una soluzione.
 

Discussioni simili