Refresh di winform durante i download

giovedì 31 maggio 2007 - 09.24

Simpz Profilo | Junior Member

Ciao a tutti,
sto creando un'applicazione con un winform che scarica dei file da una locazione su internet.
Il problema è che nonostante mi scarichi tutto e bene io, tra un download e l'altro, ho messo delle righe su una listbox ma non me le fa vedere volta per volta; me le fa vedere tutte di un botto quando è finito tutto... come posso fare?

Avevo pensato a mettere qui e la ad hoc dei metodi show()... è la strada giusta?
Grazie delle dritte

-----------------------------------

Mi autorispondo:
basta mettere dei metodi this.refresh() (ovviamente direi...)

0v3rCl0ck Profilo | Guru

Ciao,

ho visto che ti sei auto risposto, la soluzione che hai trovato funziona perchè in pratica forzi l'interfaccia grafica ad aggiornarsi obbligatoriamente e questo è giusto, però devi sapere che comunque stai lavorando sullo stesso thread di esecuzione e quindi quando obblighi l'interfaccia ad aggiornarsi, il resto delle esecuzioni si devono fermare per ridisegnare tutti i controlli, questo ovviamente può anche non essere necessariamente disastroso, ma dato che .NET ci da a disposizione la gestione a thread, ti consiglio di creare il tuo applicativo a thread separati e sincronizzare il tutto con eventi "parlanti" di callback, in questo modo puoi slacciare le elaborazioni "pesanti" dall'interfaccia, così non sarai costretto a mettere le forzature di refresh perchè il thread principale rimane sempre scarico. Però attenzione che i controlli grafici possono essere modificati SOLO sul thread principale e quindi se ad esempio vuoi fare vedere il progresso delle tue attività lanciate su un altro thread devi chiamare un evento che poi a sua volta lanci un delegato istanziato sul thread principale, e da li puoi aggiornare il controllo grafico. Se non hai familiarità con i thread quello che ti ho scritto potrà sembrare molto complesso, quindi se hai bisogno di più spiegazioni fammi sapere che ti do qualche drittta e qualche link dove potere studiare la gestione a thread dei tuoi applicativi.


Spero di esserti stato utile
Enjoy It

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

Simpz Profilo | Junior Member

infatti dopo poco stavo vedendo qualche esempio di gestione di thread soprattutto per il download di file e mi sono imbattuto sul componente backgroundworker e stavo iniziando a vedere come si gestiva... se hai dei documenti da farmi consultare posta pure!!!

Grazie

0v3rCl0ck Profilo | Guru

Bravo, il background worker è molto utile per piccole cose, perchè ti evita le complessa gestione per potere aggiornare i controlli sul thread principale, infatti il background worker l'hanno proprio introdotto per facilitare questo compito, perchè l'evento RunWorkerCompleted lavora già sul thread principale ed è quindi possibile interagire con l'interfaccia grafica. Provo a spiegartelo in un paio di passaggi:

- Trascina il controllo background worker sulla form
- Crei le funzioni per gestire gli eventi DoWork e RunWorkerCompleted
- Sul pulsante che fa partire l'elaborazione lanci la funzione RunWorkerAsync() del tuo bgworker
- Nella funzione DoWork metti tutto il codice che serve per lanciare il download, e quando ne hai il risultato lo salvi nella proprietà Result (se ti serve salvare un risultato) dell'eventargs e (e.Result) che accetta un Object.
- Nel RunWorkerCompleted fai un If e controlli se si sono verificati errori, guardando la proprietà e.Error che restituisce un dato di tipo Exception se qualcosa è andato storto nel DoWork. Se non si sono verificati errori passi a leggere e.Result ed elaborare quello che ti interessa fare e poi puoi scrivere sulla form avvisando l'utente che è finito, eccc....
- Se ti servono dei progress intermedi utilizza la funzione ReportProgress(Integer) dentro all'evento OnWork e intercettalo con l'evento ProgressChanged. Ricordati però di abilitare il bgworker per il progress mettendo a True la proprietà WorkerReportsProgress. Un altra cosa molto importante quando devi interagire con il bgworker da dentro gli eventi che lancia esso, di castare ed utilizzare l'oggetto sender facendo un bel: Dim bgWorker As BackgroundWorker = CType(sender, BackgroundWorker), altrimenti se usi Me.NomeBackgroundWorker non funziona perchè in realtà .net penso crei una nuova istanza quando lancia il bgworker.

Questo è il link alla documentazione su MSDN: http://msdn2.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx


Enjoy It


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

Simpz Profilo | Junior Member

grazie delle dritte... proverò a fare qualcosa!

L'unica cosa è che non capisco se all'evento dowork gli posso passare un argomento, visto che devo scaricare un array di files...

------------------

Trovato tutto!!!
chiamo il dowork con l'argomento e poi nel metodo dowork lo richiamo con e.argument castandolo a quello che mi serve

0v3rCl0ck Profilo | Guru

Si, puoi passargli un argomento quando lanci l'esecuzione: RunWorkerAsync(Argument)
poi quando sei nell'evento DoWork puoi leggere il parametro da e.Argument

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

Simpz Profilo | Junior Member

nel metodo RunWorkerCompleted posso usare i controlli della form per fargli fare quello che voglio?

0v3rCl0ck Profilo | Guru

si è proprio quella la comodità dei bgworker
http://blogs.dotnethell.it/Regulator/

0v3rCl0ck Profilo | Guru

ciao,

accetti la risposta, così chiudiamo il post

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

Simpz Profilo | Junior Member

scusa la dimenticanza...
fatto

0v3rCl0ck Profilo | Guru

Non ti preoccupare, grazie

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