Correzione di questo codice con l'utilizzo del backgroundworker

mercoledì 23 gennaio 2008 - 18.09

trinity Profilo | Guru

Ragazzi,
sto impazzendo penso di aver scritto tutto bene ma l'evento BackgroundWorker1_ProgressChanged si attiva una sola volta.
Vi prego posto tutto il codice potete darci un'occhiata?

premetto la proprietà BackgroundWorker1.WorkerReportsProgress è impostata su True

comunque ecco il codice:

come avvio l'oggetto BackgroundWorker:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Il codice nell'evento DoWork

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

il codice nell'evento ProgressChanged

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Come dicevo tramite il debug il compilatore passa una sola volta nell'evento ProgressChanged


HELP ME!!!!
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

0v3rCl0ck Profilo | Guru

>Ragazzi,

Ciao

>sto impazzendo penso di aver scritto tutto bene ma l'evento BackgroundWorker1_ProgressChanged
>si attiva una sola volta.
>Vi prego posto tutto il codice potete darci un'occhiata?
>
>premetto la proprietà BackgroundWorker1.WorkerReportsProgress
>è impostata su True
>

Il problema sta nel fatto, che lanci il progress utilizzando l'istanza creata sul thread principale (Me.BackgroundWorker1), mentre devi necessariamente utilizzare l'istanza che ti passa lui nel sender dell'evento DoWork.

Eccoti il codice modificato:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Come puoi vedere ho soltanto aggiunto "Dim MyBackgroundWorker As System.ComponentModel.BackgroundWorker = CType(sender, System.ComponentModel.BackgroundWorker)" e sostituito i Me.BackgroundWorker1 con MyBackgroundWorker.

Spero di esserti stato di aiuto.


Enjoy It
http://blogs.dotnethell.it/Regulator/

trinity Profilo | Guru

Niente ho messo come mi hai scritto e sull'evento ProgressChanged ci va una volta sola.

ma intanto ti voglio dire che per lanciare l'esecuzione dell'oggetto backgroundworker scrivo il seguente codice: Me.BackgroundWorker1.RunWorkerAsync()

è giusto? Oppure devo fare anche qui la dichiarazione che hai scritto te?

ti ri-posto tutto il codice:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra


Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

0v3rCl0ck Profilo | Guru

C'è un errore logico nelle due righe di codice:

For y As Integer = 0 To C59Coll.Count - 1 y += 1

la variabile 'y' viene già utilizzata e incrementata dal costrutto FOR, quindi se tu ulteriormente la incrementi, non solo il ciclo finirà prima del C59Coll.Count, ma potrebbe anche creare problemi al progresschange, sicuramente se ad esempio la C59Coll.Count vale 2, il progresschange viene lanciato solo 1 volta, ma proprio perchè il ciclo "muore" subito. Prova a darci un occhio.

In ogni caso di sto preparando un progettino di esempio.


http://blogs.dotnethell.it/Regulator/

trinity Profilo | Guru

>C'è un errore logico nelle due righe di codice:
>
>For y As Integer = 0 To C59Coll.Count - 1
> y += 1

Ho tolto y += 1 ma quando esegue il ciclo for, la progresschange viene attivata una sola volta ancora ed in + ad una certa durate l'esecuzione del ciclo for il compilatore si blocca senza indicandomi la riga di codice errata e mi esce questo errore:

TargetInvocationException non è stata gestita
Eccezione generata dalla destinazione di una chiamata.

Non so cosa fare onestamente...

>la variabile 'y' viene già utilizzata e incrementata dal costrutto
>FOR, quindi se tu ulteriormente la incrementi, non solo il ciclo
>finirà prima del C59Coll.Count, ma potrebbe anche creare problemi
>al progresschange, sicuramente se ad esempio la C59Coll.Count
>vale 2, il progresschange viene lanciato solo 1 volta, ma proprio
>perchè il ciclo "muore" subito. Prova a darci un occhio.
>
>In ogni caso di sto preparando un progettino di esempio.
>
>
>http://blogs.dotnethell.it/Regulator/

Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

0v3rCl0ck Profilo | Guru

>>C'è un errore logico nelle due righe di codice:
>>
>>For y As Integer = 0 To C59Coll.Count - 1
>> y += 1
>
>Ho tolto y += 1 ma quando esegue il ciclo for, la progresschange
>viene attivata una sola volta ancora ed in + ad una certa durate
>l'esecuzione del ciclo for il compilatore si blocca senza indicandomi
>la riga di codice errata e mi esce questo errore:
>
>TargetInvocationException non è stata gestita
>Eccezione generata dalla destinazione di una chiamata.
>
>Non so cosa fare onestamente...

Devi controllare bene la logica del ciclo...e metti un breakpoint nel catch dell'eccezione all'interno del metodo DoWork.

>
>>la variabile 'y' viene già utilizzata e incrementata dal costrutto
>>FOR, quindi se tu ulteriormente la incrementi, non solo il ciclo
>>finirà prima del C59Coll.Count, ma potrebbe anche creare problemi
>>al progresschange, sicuramente se ad esempio la C59Coll.Count
>>vale 2, il progresschange viene lanciato solo 1 volta, ma proprio
>>perchè il ciclo "muore" subito. Prova a darci un occhio.
>>
>>In ogni caso di sto preparando un progettino di esempio.
>>


Intanto dai un occhio anche al progetto che ti ho allegato, dove c'è un semplice esempio su come usare il ProgressChange.


http://blogs.dotnethell.it/Regulator/

trinity Profilo | Guru

Ok funziona sbagliavo io un codice nella progresschanged...cmq, io stavo controllando l'avanzamento della progressbar e noto che la e.ProgressPercentage non è rapportata alla proprietà maximum della progressbar. dove posso impostare questo valore nella Dowork?

ciao e grazie
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

0v3rCl0ck Profilo | Guru

>Ok funziona sbagliavo io un codice nella progresschanged...

Bene

>cmq, io stavo controllando l'avanzamento della progressbar e noto
>che la e.ProgressPercentage non è rapportata alla proprietà maximum
>della progressbar. dove posso impostare questo valore nella Dowork?

Nella proprietà ProgressPercentage può essere impostato un qualsiasi numero Int32, quindi poi sarai tu a dovere gestire la logica che ci sta sotto. Dovrai impostare il maxvalue della progressbar in maniera opportuna per avere il numero totale di cicli che devi fare nel do work. Se questo valore lo puoi soltanto sapere all'interno del metodo DoWork, potresti lanciare un ReportProgress specificando i due parametri così: ReportProgress(NumeroTotaliCicli, True), dove True ti servirà per capire che dentro a e.ProgressPercentage c'è il numero totali di cicli, in questo modo nell'evento 'ProgressChanged', controllerai con un if la proprietà e.UserState e se è a true, imposti il maxvalue della progressbar e poi esci dalla funzione. I successivi 'ProgressChanged' invece faranno avanzare la progressbar.



http://blogs.dotnethell.it/Regulator/

trinity Profilo | Guru

>>Ok funziona sbagliavo io un codice nella progresschanged...
>
>Bene
>
>>cmq, io stavo controllando l'avanzamento della progressbar e noto
>>che la e.ProgressPercentage non è rapportata alla proprietà maximum
>>della progressbar. dove posso impostare questo valore nella Dowork?
>
>Nella proprietà ProgressPercentage può essere impostato un qualsiasi
>numero Int32, quindi poi sarai tu a dovere gestire la logica
>che ci sta sotto. Dovrai impostare il maxvalue della progressbar
>in maniera opportuna per avere il numero totale di cicli che
>devi fare nel do work. Se questo valore lo puoi soltanto sapere
>all'interno del metodo DoWork, potresti lanciare un ReportProgress
>specificando i due parametri così: ReportProgress(NumeroTotaliCicli,
>True), dove True ti servirà per capire che dentro a e.ProgressPercentage
>c'è il numero totali di cicli, in questo modo nell'evento 'ProgressChanged',
>controllerai con un if la proprietà e.UserState e se è a true,
>imposti il maxvalue della progressbar e poi esci dalla funzione.
>I successivi 'ProgressChanged' invece faranno avanzare la progressbar.
>

Aspetta non ti seguo:

io nella dowork setto così:

MyBackgroundWorker.ReportProgress(TotRecord, True)

poi però nella progresschanged io ho scritto prima così:

Me.ProgressBar1.Value = e.ProgressPercentage

ora ho scritto così:

Dim p As Boolean
p = CBool(e.UserState.ToString)
If p = True Then
Me.ProgressBar1.Maximum = e.ProgressPercentage
Exit Sub
End If

ma non ha senso perchè così esco sempre dall'evento e poi il valore della progressbar.value come faccio a settarla?


senti ultima cosa come faccio a bloccare il thread? devo utilizzare il metodo
CancelAsync()

ma con direttamente l'oggetto BackgroundWorker della form?
>http://blogs.dotnethell.it/Regulator/

Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

0v3rCl0ck Profilo | Guru

>Aspetta non ti seguo:
>
>io nella dowork setto così:
>
> MyBackgroundWorker.ReportProgress(TotRecord, True)
>
>poi però nella progresschanged io ho scritto prima così:
>
> Me.ProgressBar1.Value = e.ProgressPercentage
>
>ora ho scritto così:
>
> Dim p As Boolean
> p = CBool(e.UserState.ToString)
> If p = True Then
> Me.ProgressBar1.Maximum = e.ProgressPercentage
> Exit Sub
> End If


Sarebbe così:

If e.UserState IsNot Nothing AndAlso DirectCast(e.UserState, Boolean) Then Me.ProgressBar1.Maximum = e.ProgressPercentage Me.ProgressBar1.Step = 1 Else Me.ProgressBar1.Value = e.ProgressPercentage End If


>
>ma non ha senso perchè così esco sempre dall'evento e poi il
>valore della progressbar.value come faccio a settarla?
>
>
>senti ultima cosa come faccio a bloccare il thread? devo utilizzare
>il metodo
>CancelAsync()


Sinceramente non l'ho ancora approfondito quel discorso...Dovresti documentarti
Comunque in linea di massima, si il comando da approfondire è il CancelSync() che ti imposterà poi la proprietà CancellationPending del BackgroundWorker in esecuzione.


>
>ma con direttamente l'oggetto BackgroundWorker della form?


Dentro agli eventi devi utilizzare SEMPRE il sender, e sarebbe meglio come regola generale



http://blogs.dotnethell.it/Regulator/

trinity Profilo | Guru

un secondo.

nell'evento Do_Work ho scritto così:

MyBackgroundWorker.ReportProgress(totrecordalb, True)

nell'evento ProgressChanged ho scritto come mi hai suggerito:

If e.UserState IsNot Nothing AndAlso DirectCast(e.UserState, Boolean) Then

Me.ProgressBar1.Maximum = e.ProgressPercentage
Me.ProgressBar1.Step = 1

Else

Me.ProgressBar1.Value = e.ProgressPercentage

End If

ma il codice esegue sempre la parte "Me.ProgressBar1.Maximum = e.ProgressPercentage" non passa mai a " Me.ProgressBar1.Value = e.ProgressPercentage".



senti poi stavo anche utilizzado la proprietà ISbusy

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Me.BackgroundWorker1.IsBusy = True Then
MessageBox.Show("Attenzione è già in corso un processo di eleborazione", "Receive.Net", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Return
End If
Me.BackgroundWorker1.RunWorkerAsync()
End Sub

ma appena il compilatore passa sulla messagebox esce l'errore:

TargetInvocationException non è stata gestita
Eccezione generata dalla destinazione di una chiamata.
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

0v3rCl0ck Profilo | Guru

>un secondo.
>
>nell'evento Do_Work ho scritto così:
>
> MyBackgroundWorker.ReportProgress(totrecordalb, True)
>
>nell'evento ProgressChanged ho scritto come mi hai suggerito:
>
>If e.UserState IsNot Nothing AndAlso DirectCast(e.UserState,
>Boolean) Then
>
> Me.ProgressBar1.Maximum = e.ProgressPercentage
> Me.ProgressBar1.Step = 1
>
> Else
>
> Me.ProgressBar1.Value = e.ProgressPercentage
>
> End If
>
>ma il codice esegue sempre la parte "Me.ProgressBar1.Maximum
>= e.ProgressPercentage" non passa mai a " Me.ProgressBar1.Value
>= e.ProgressPercentage".
>


Solo la prima volta devi chiamare la MyBackgroundWorker.ReportProgress(totrecordalb, True) dopo devi chiamarla senza il True MyBackgroundWorker.ReportProgress(y)


>
>
>senti poi stavo anche utilizzado la proprietà ISbusy
>
>Private Sub Button1_Click(ByVal sender As System.Object, ByVal
>e As System.EventArgs) Handles Button1.Click
> If Me.BackgroundWorker1.IsBusy = True Then
>MessageBox.Show("Attenzione è già in corso un processo di eleborazione",
>"Receive.Net", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
> Return
> End If
> Me.BackgroundWorker1.RunWorkerAsync()
> End Sub
>
>ma appena il compilatore passa sulla messagebox esce l'errore:
>
>TargetInvocationException non è stata gestita
>Eccezione generata dalla destinazione di una chiamata.


Qui devi fare qualche prova. Togli ad esempio il Return e fallo con un semplice If Then ELSE... fammi sapere



http://blogs.dotnethell.it/Regulator/

trinity Profilo | Guru

senti io sto provando il metodo cancelasync ma non funge ho visto anche molti esempi e mi pare che il codice che ho utilizzato sia corretto.
Te non hai mai provato a bloccare l'esecuzione dell'oggetto BW?

Ciao
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

0v3rCl0ck Profilo | Guru

>senti io sto provando il metodo cancelasync ma non funge ho visto
>anche molti esempi e mi pare che il codice che ho utilizzato
>sia corretto.
>Te non hai mai provato a bloccare l'esecuzione dell'oggetto BW?


eh no, non ne ho mai avuto la necessità...



http://blogs.dotnethell.it/Regulator/
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5