Logo UGIdotNET

Discussione 'Form con ProgressBar in un thread secondario'

# Pubblicato il 13 ago 2004 10.29 - Rispondi
Jonathan Zanardi
Form con ProgressBar in un thread secondario
Ciao a tutti,
sto cercando di aggiungere alla mia applicazione un form con una barra di progresso che venga mostrata quando l'utente compie operazioni particolarmente lunghe.

L'applicazione è sviluppata in .NET CompactFramework.

Non potendo suddividere l'operazione in vari step e quindi controllare direttamente l'avanzamento della barra di progresso avevo pensato di mostrare una barra che si riempie e si svuota continuamente finchè l'operazione è terminata. A quel punto distruggo la form con la progressbar. Per realizzare questo effetto pensavo bastasse mostrare la form con .Show() (NON MODALE) ed inserire nella gestione dell'evento OnLoad un ciclo while infinito in cui far avanzare e regredire la progressbar.
Il problema è che così facendo l'elaborazione si blocca sull'evento Load del form secondario e non avanza più.
Dovrei quindi portare il Form su un altro thread ma come si fa?
Ho visto che bisogna istanziare un ThreadStart delegate e un oggetto Thread richiamando Thread.Start ma poi come lo chiudo? Nel CompactFramework non c'è nessun metodo Abort() o altro per chiudere il Thread.....

Grazie
Bye
John
# Pubblicato il 14 ago 2004 0.22 - Rispondi
Corrado Cavalli [MVP]
Re: Form con ProgressBar in un thread secondario

> Dovrei quindi portare il Form su un altro thread ma come si fa?
> Ho visto che bisogna istanziare un ThreadStart delegate e un oggetto
> Thread richiamando Thread.Start ma poi come lo chiudo?

[STAThread]
static void Main(string[] args)
{

Thread T=new Thread(new ThreadStart(MyFn));
T.Start();
}

private void MyFn()
{
for(int i=0;i<10;i++)
{
...
}
}

Il thread 'muore' quando l'esecuzione di MyFn termina, non devi killarlo
tu...


--
Corrado Cavalli [Microsoft .NET MVP-MCP]
UGIdotNET - http://www.ugidotnet.org
Weblog: http://www.ugidotnet.org/710.blog



--
Questo messaggio è stato postato da microsoft.public.it.dotnet.csharp.
# Pubblicato il 16 ago 2004 18.24 - Rispondi
Andrea Raimondi
Re: Form con ProgressBar in un thread secondario

Ciao,

Non sono un esperto del framework, ma ecco comunque i
miei commenti...

UGI 7490 wrote:

> Non potendo suddividere l'operazione in vari step e quindi controllare
> direttamente l'avanzamento della barra di progresso

Non so, magari sbaglio io, ma in genere quando si verificano cose di
questo tipo andrebbe rivisto il design, IMVHO.

> una barra che si riempie e si svuota continuamente finchè l'operazione è
> terminata. A quel punto distruggo la form con la progressbar. Per realizzare
> questo effetto pensavo bastasse mostrare la form con .Show() (NON MODALE) ed
> inserire nella gestione dell'evento OnLoad un ciclo while infinito in cui far
> avanzare e regredire la progressbar.

Mi sembra accettabile.

> Il problema è che così facendo l'elaborazione si blocca sull'evento Load del
> form secondario e non avanza più.

Uhm... tu sei sicuro di questa cosa, vero?
Sinceramente mi sembra strano. Impossibile no,
dati i possibili problemi di focus, ma abbastanza strano si.

> Dovrei quindi portare il Form su un altro thread ma come si fa?
> Ho visto che bisogna istanziare un ThreadStart delegate e un oggetto Thread
> richiamando Thread.Start ma poi come lo chiudo? Nel CompactFramework non c'è
> nessun metodo Abort() o altro per chiudere il Thread.....

IMVHO: non devi assolutamente riportare la form su un altro
thread, anzi, ti conviene molto di più portare IL CALCOLO
nell'altro thread. Il motivo di questo è semplicemente che l'uso dei
threads è già abbastanza complesso senza mettere in mezzo le
risorse grafiche del framework, figuriamoci poi se ci metti un
form. Appropò, ma dotNET mi risulta che non sia proprio
vanilla quando si parla di multithreading, ho letto male?

> Grazie

My 2c,

Andrea
--
Questo messaggio è stato postato da microsoft.public.it.dotnet.csharp.
# Pubblicato il 22 ago 2004 17.47 - Rispondi
Acquarius soft
Re: Form con ProgressBar in un thread secondario
perchè invece di un form non usi il cursore di attesa?
Quello classico che viene visualizzato quando windows ce è in attesa o stà avviando un programma?

Ciao
# Pubblicato il 18 ago 2004 15.39 - Rispondi
Jonathan Zanardi
Re: Form con ProgressBar in un thread secondario
on 14. Aug 2004 00:22 Corrado Cavalli [MVP] wrote:
> [STAThread]
Cos'è? a cosa serve? ho letto della necessità di specificarlo ma perchè?

> static void Main(string[] args)
> {
>
> Thread T=new Thread(new ThreadStart(MyFn));
> T.Start();
> }
>
> private void MyFn()
> {
> for(int i=0;i<10;i++)
> {
> ...
> }
> }

La soluzione a cui ero arrivato assomiglia molto al tuo consiglio tranne che per due differenze:
1) il metodo passato a ThreadStart è statico!
2) il metodo passato a ThreadStart deve poter essere concluso da un altro thread e non semplicemente raggiungere un limite con un numeratore.... quindi il corpo del metodo è del tipo

private void MyFn()
{
{....CreazioneFormdiAttesa....}
while( varBooleana)
{....animazione form di attesa...}

{....Chiusura Form di attesa....}
}
E con un metodo statico imposto la "varBooleana" a true o false!

Il problema è che a volte non si chiude il form. Può darsi che questo dipenda dal fatto che a volte viene richiamata la visualizzazione di questo form di attesa più volte a breve distanza l'una dall'altra forse prima che venga distrutto il form precedente. Devo ancora capire come risolvere il problema.... certo che senza Wait e Kill non sarà facile... probabilmente sceglierò un'altra strada.....

Grazie
Bye
John
# Pubblicato il 18 ago 2004 15.44 - Rispondi
Jonathan Zanardi
Re: Form con ProgressBar in un thread secondario
on 16. Aug 2004 18:24 Andrea Raimondi wrote:
> > Non potendo suddividere l'operazione in vari step e quindi controllare
> > direttamente l'avanzamento della barra di progresso
>
> Non so, magari sbaglio io, ma in genere quando si verificano cose di
> questo tipo andrebbe rivisto il design, IMVHO.
Nessun problema di design. Il fatto è che l'elaborazione che porta via tempo è un'unica chiamata all'oggetto SqlCeReplication.synchronize().... non ho quindi la possibilità di suddividere l'elaborazione perchè è un metodo al cui codice non posso accedere!

>
> Uhm... tu sei sicuro di questa cosa, vero?
> Sinceramente mi sembra strano. Impossibile no,
> dati i possibili problemi di focus, ma abbastanza strano si.

Certo.
La soluzione che ho trovato è quella che ho descritto nell'altra risposta che ho dato a Corrado (in questo thread).... ma ho ancora dei problemi.

> IMVHO: non devi assolutamente riportare la form su un altro
> thread, anzi, ti conviene molto di più portare IL CALCOLO
> nell'altro thread. Il motivo di questo è semplicemente che l'uso dei
> threads è già abbastanza complesso senza mettere in mezzo le
> risorse grafiche del framework, figuriamoci poi se ci metti un
> form. Appropò, ma dotNET mi risulta che non sia proprio
> vanilla quando si parla di multithreading, ho letto male?
Mi sono reso conto del limitato supporto al threading nel CompactFramework ma portare l'elaborazione su un working thread non mi interessa in quanto non devo eseguire pesanti lavori di aggiornamento di interfaccia e contemporaneamente elaborazione dati.... vorrei solo poter mostrare un form con un'animazione di attesa!

Bye
John
# Pubblicato il 18 ago 2004 20.10 - Rispondi
Andrea Raimondi
Re: Form con ProgressBar in un thread secondario

UGI 7490 wrote:

> Nessun problema di design. Il fatto è che l'elaborazione che porta via tempo è
> un'unica chiamata all'oggetto SqlCeReplication.synchronize().... non ho quindi
> la possibilità di suddividere l'elaborazione perchè è un metodo al cui codice
> non posso accedere!

Come detto e ripetuto mille volte, del framework non me ne intendo,
quindi magari sto dicendo una boiata cosmica, ma sei proprio
certo che non vi sia uno o più eventi che ti supportano durante la
replica?

> Mi sono reso conto del limitato supporto al threading nel CompactFramework ma
> portare l'elaborazione su un working thread non mi interessa in quanto non devo
> eseguire pesanti lavori di aggiornamento di interfaccia e contemporaneamente
> elaborazione dati.... vorrei solo poter mostrare un form con un'animazione di
> attesa!

IMHO: insisto nel consigliarti di portare quella istruzione in un
worker thread. Quello che devi fare sarà anche non laborioso, non
discuto, però ti semplifichi molto la vita con un worker thread,
poiché ti basta una notifica di qualunque genere da inviare alla
form per chiudersi.

Ho provato a guardare sulla documentazione di .NET Framework,
effettivamente non sembrano esserci eventi da gestire(?) per questo
genere di necessità.

Ciao,

> John

Andrea
--
Questo messaggio è stato postato da microsoft.public.it.dotnet.csharp.
# Pubblicato il 19 ago 2004 9.00 - Rispondi
Jonathan Zanardi
Re: Form con ProgressBar in un thread secondario
on 18. Aug 2004 20:10 Andrea Raimondi wrote:
>
> Come detto e ripetuto mille volte, del framework non me ne intendo,
> quindi magari sto dicendo una boiata cosmica, ma sei proprio
> certo che non vi sia uno o più eventi che ti supportano durante la
> replica?

Sicuro al 100%. E' un'unica chiamata inscindibile!

> IMHO: insisto nel consigliarti di portare quella istruzione in un
> worker thread. Quello che devi fare sarà anche non laborioso, non
> discuto, però ti semplifichi molto la vita con un worker thread,
> poiché ti basta una notifica di qualunque genere da inviare alla
> form per chiudersi.

No, non è giustificabile riscrivere tutta l'applicazione per mettere l'elaborazione in un worker thread che consenta ad un Form di attesa di poter apparire.... proprio no!
Ripeto, una scelta del genere si può giustificare se mentre viene eseguita l'elaborazione è necessario che l'interfaccia rimanga interattiva con l'utente.... ma in questo caso.....

Grazie comunque
Bye
John
# Pubblicato il 19 ago 2004 10.05 - Rispondi
Andrea Raimondi
Re: Form con ProgressBar in un thread secondario

UGI 7490 wrote:

> Sicuro al 100%. E' un'unica chiamata inscindibile!

Sulla chiamata non avevo dubbi, ma mi ero chiesto se
magari c'era qualche evento OnProgress o robe simili,
però pare proprio che non c'è( chissà perché poi ).

> No, non è giustificabile riscrivere tutta l'applicazione per mettere
> l'elaborazione in un worker thread che consenta ad un Form di attesa di poter
> apparire.... proprio no!

Io non ho *mai* parlato di riscrivere tutta l'applicazione, non
sono rincitrullito!

Parlavo della *sola* istruzione Synchronize, da mettere in un
worker thread.

> Ripeto, una scelta del genere si può giustificare se mentre viene eseguita
> l'elaborazione è necessario che l'interfaccia rimanga interattiva con
> l'utente.... ma in questo caso.....

A parte il fatto che se vuoi mostrare un form con una
progress bar, quella mi sembra una cosa "interattiva con l'utente", ma
ripeto, io parlavo della *sola* synchronize e non credo che tutta
l'applicazione sia composta di quella sola istruzione, no?

Non v'è nemmeno bisogni che la sposti l'istruzione, ti basta
metterci un bel lock e sei a posto!

Ad ogni modo, per cercare di venir fuori da questa cosa l'ideale
imho sarebbe di poter materialmente vedere la parte interessata in
sorgente.

> Grazie comunque

Prego,

> Bye

Rgds,

> John

Andrea
--
Questo messaggio è stato postato da microsoft.public.it.dotnet.csharp.
# Pubblicato il 10 set 2004 10.23 - Rispondi
Jonathan Zanardi
Re: Form con ProgressBar in un thread secondario
on 22. Aug 2004 17:47 Acquarius soft wrote:
> perchè invece di un form non usi il cursore di attesa?
> Quello classico che viene visualizzato quando windows ce è in attesa o stà avviando
> un programma?
Perchè sul portatile il cursore di attesa appare solo quando l'utente prova a cliccare da qualche parte... altrimenti non si vede niente.... certo nel momento in cui clicca di accorge che l'elaborazione sta continuando però non è granché

Bye
John

© 2001 User Group Italiano UGIdotNET. Tutti i diritti riservati. Note legali. - Partita IVA 01927050185