Torna indietro   Hardware Upgrade Forum > Software > Programmazione

HP Elitebook Ultra G1i 14 è il notebook compatto, potente e robusto
HP Elitebook Ultra G1i 14 è il notebook compatto, potente e robusto
Pensato per il professionista sempre in movimento, HP Elitebook Ultra G1i 14 abbina una piattaforma Intel Core Ultra 7 ad una costruzione robusta, riuscendo a mantenere un peso contenuto e una facile trasportabilità. Ottime prestazioni per gli ambiti di produttività personale con un'autonomia lontano dalla presa di corrente che permette di lavorare per tutta la giornata
Microsoft Surface Pro 12 è il 2 in 1 più compatto e silenzioso
Microsoft Surface Pro 12 è il 2 in 1 più compatto e silenzioso
Basato su piattaforma Qualcomm Snapdragon X Plus a 8 core, il nuovo Microsoft Surface Pro 12 è un notebook 2 in 1 molto compatto che punta sulla facilità di trasporto, sulla flessibilità d'uso nelle differenti configurazioni, sul funzionamento senza ventola e sull'ampia autonomia lontano dalla presa di corrente
Recensione REDMAGIC Astra Gaming Tablet: che spettacolo di tablet!
Recensione REDMAGIC Astra Gaming Tablet: che spettacolo di tablet!
Il REDMAGIC Astra Gaming Tablet rappresenta una rivoluzione nel gaming portatile, combinando un display OLED da 9,06 pollici a 165Hz con il potente Snapdragon 8 Elite e un innovativo sistema di raffreddamento Liquid Metal 2.0 in un form factor compatto da 370 grammi. Si posiziona come il tablet gaming più completo della categoria, offrendo un'esperienza di gioco senza compromessi in mobilità.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 26-12-2009, 10:23   #1
voyager18
Member
 
Iscritto dal: Aug 2007
Messaggi: 138
[WIN FORM .NET] Eseguire operazioni sul form mentre è in corso una routine

Ho un windows form che al click di un pulsante esegue un'operazione un pò lunga. Nel form c'è anche una label che durante la routine vorrei che assumesse valori diversi. Ho provato ad impostare il testo della label ma non viene visualizzato fin quando la routine non finisce di lavorare. C'è un modo per far eseguire il rendering della label mentre la routine sta girando?
voyager18 è offline   Rispondi citando il messaggio o parte di esso
Old 26-12-2009, 10:32   #2
Energy++
Senior Member
 
Iscritto dal: Oct 2005
Messaggi: 1044
la tua routine la devi far eseguire su un thread diverso, se no è normale che la gui rimanga bloccata.
Il modo più semplice di fare questo secondo me è utilizzare la classe BackgroundWorker.
Il tutorial è molto chiaro, se comunque hai problemi non esitare a chiedere
Energy++ è offline   Rispondi citando il messaggio o parte di esso
Old 26-12-2009, 12:35   #3
MarcoGG
Senior Member
 
L'Avatar di MarcoGG
 
Iscritto dal: Dec 2004
Messaggi: 3210
Quote:
Originariamente inviato da voyager18 Guarda i messaggi
Ho un windows form che al click di un pulsante esegue un'operazione un pò lunga. Nel form c'è anche una label che durante la routine vorrei che assumesse valori diversi. Ho provato ad impostare il testo della label ma non viene visualizzato fin quando la routine non finisce di lavorare. C'è un modo per far eseguire il rendering della label mentre la routine sta girando?
Basta che aggiungi un Application.DoEvents() subito dopo la linea di codice in cui modifichi il testo della Label, e dovresti già aver risolto. Con una riga eviti di scomodare multithreading e magari di trovarti anche a gestire operazioni cross-thread, per cosucce come questa...
MarcoGG è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 11:31   #4
CwNd
Senior Member
 
L'Avatar di CwNd
 
Iscritto dal: Jun 2007
Città: Milano
Messaggi: 413
Non sono tanto d'accordo con l'uso del metodo DoEvents.
E' sicuramente vero che in modo semplice riesci a fare quello che ti serve, ovvero aggiornare la label, ma il form rimane comunque bloccato nel tempo che intercorre tra le due chiamate al metodo DoEvents. Inoltre può essere utile, mentre è in corso questa elaborazione un po' lunga, che l'utente possa fare altre operazioni con il programma, cosa che non è fattibile se l'elaborazione è fatta nel thread della gui.
L'uso di BackgroundWorker o comunque di thread specifici per ogni computazione lunga è sicuramente una scelta un po' più complicata da realizzare ma che sicuramente paga in termini di usabilità, versatilità e performances.
CwNd è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 13:07   #5
MarcoGG
Senior Member
 
L'Avatar di MarcoGG
 
Iscritto dal: Dec 2004
Messaggi: 3210
Quote:
Originariamente inviato da CwNd Guarda i messaggi
Non sono tanto d'accordo con l'uso del metodo DoEvents.
E' sicuramente vero che in modo semplice riesci a fare quello che ti serve, ovvero aggiornare la label, ma il form rimane comunque bloccato nel tempo che intercorre tra le due chiamate al metodo DoEvents. Inoltre può essere utile, mentre è in corso questa elaborazione un po' lunga, che l'utente possa fare altre operazioni con il programma, cosa che non è fattibile se l'elaborazione è fatta nel thread della gui.
L'uso di BackgroundWorker o comunque di thread specifici per ogni computazione lunga è sicuramente una scelta un po' più complicata da realizzare ma che sicuramente paga in termini di usabilità, versatilità e performances.
Se la richiesta era semplicemente questa : "C'è un modo per far eseguire il rendering della label mentre la routine sta girando", direi che DoEvents è la risposta più adatta, oltre che la più immediata.
Inoltre non è affatto vero, come dici, che l'interazione con la gui non sia fattibile dallo stesso thread. Basta verificare se c'è stata interazione dell'utente con GetInputState :
http://www.dotnet2themax.it/ShowCont...3-48e19d3cf6a5

Che poi, in casi più complessi il multithread sia praticamente d'obbligo è un altro discorso, ma per il refresh di una Label mi sembra uno spreco.
MarcoGG è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 13:39   #6
CwNd
Senior Member
 
L'Avatar di CwNd
 
Iscritto dal: Jun 2007
Città: Milano
Messaggi: 413
Quote:
Originariamente inviato da MarcoGG Guarda i messaggi
Se la richiesta era semplicemente questa : "C'è un modo per far eseguire il rendering della label mentre la routine sta girando", direi che DoEvents è la risposta più adatta, oltre che la più immediata.
Inoltre non è affatto vero, come dici, che l'interazione con la gui non sia fattibile dallo stesso thread.
Potrai si verificare se c'è l'interazione o meno, ma se una istruzione è bloccante (come ad esempio un download sincrono di un file), durante quel tempo la gui è bloccata.

Comunque la domanda l'avevo letta bene, e non discuto che con il metodo DoEvents possa funzionare, ritengo solo che sia una soluzione veloce ma che vale ben poco.
CwNd è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 14:31   #7
MarcoGG
Senior Member
 
L'Avatar di MarcoGG
 
Iscritto dal: Dec 2004
Messaggi: 3210
Quote:
Originariamente inviato da CwNd Guarda i messaggi
Potrai si verificare se c'è l'interazione o meno, ma se una istruzione è bloccante (come ad esempio un download sincrono di un file), durante quel tempo la gui è bloccata.
Se l'operazione è bloccante e costituita da un'istruzione unica, come un download ( My.Computer.Network.DownloadFile(link, target) ), come fai ad aggiornare una Label ?
Non penso fosse l'intenzione di voyager18.
Potrei sbagliarmi, ma credo si tratti di una sua routine ciclica, da qui la mia risposta. In ogni caso finchè voyager18 non si fa vivo con info più precise, resto dell'idea che DoEvents sia da preferirsi nei casi molto semplici, come penso sia questo.
MarcoGG è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 15:17   #8
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12093
Io sono assolutamente contrario a bloccare il thread della GUI.
Non c'è niente di peggio che possa essere fatto.
In questo modo viene bloccata anche tutta la gestione degli eventi, e il programma si comporta come se fosse in hang, inoltre non credo sia affatto scontato che il rendering della label venga effettuato correttamente, o meglio, quantomeno con java era scritto *esplicitamente* questo, ma ad occhio direi che possa valere anche per le winforms.
Quantomeno, in caso non si voglia usare un backgroundworker, sarebbe opportuno utilizzare dei delegate con BeginInvoke per mandare in background l'esecuzione del metodo bloccante.
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 15:27   #9
CwNd
Senior Member
 
L'Avatar di CwNd
 
Iscritto dal: Jun 2007
Città: Milano
Messaggi: 413
Quote:
Originariamente inviato da ^TiGeRShArK^ Guarda i messaggi
inoltre non credo sia affatto scontato che il rendering della label venga effettuato correttamente
Questo è verissimo!

Quote:
Se l'operazione è bloccante e costituita da un'istruzione unica, come un download ( My.Computer.Network.DownloadFile(link, target) ), come fai ad aggiornare una Label ?
Il mio era solo un esempio per farti capire che anche con un bel DoEvents() e pur sfruttando il metodo che menzionavi sopra otterresti un bel freeze della gui.

Detto questo, io non volevo sindacare sull'istruzione, conosco bene quello che fa, ma ritengo che vada usata il meno possibile per questo genere di cose perchè potrebbe portare a spiacevoli risultati.
CwNd è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 15:53   #10
Energy++
Senior Member
 
Iscritto dal: Oct 2005
Messaggi: 1044
condivido le risposte degli utenti ^TiGeRShArK^ e CwNd per questo avevo fin da subito proposto il backgroundworker
Energy++ è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 16:07   #11
MarcoGG
Senior Member
 
L'Avatar di MarcoGG
 
Iscritto dal: Dec 2004
Messaggi: 3210
Quote:
Originariamente inviato da CwNd Guarda i messaggi
Il mio era solo un esempio per farti capire che anche con un bel DoEvents() e pur sfruttando il metodo che menzionavi sopra otterresti un bel freeze della gui.
1. Ma è proprio questo il punto. Il tuo esempio non calza, in quanto se la tua operazione è un'istruzione sola, il refresh della Label DOVE lo agganci ?
"Anche con il DoEvents" non c'entra un fico. Ovvio che se fai il download con singola istruzione non lo usi, il DoEvents, perchè non sai manco dove metterlo, che razza di discorso è ?!
E nemmeno col tuo multithread riesci a cavare un ragno da un buco in quel caso. Prova a mettere la percentuale del file scaricato in una Label con My.Computer.Network.DownloadFile(), con o senza multithread, e fammi sapere.

2. La tecnica che ho linkato più sopra è valida. L'ho usata personalmente, funziona, e la consiglio. Poi starà a chi ha domandato farne l'uso che crede.
Secondo me chi ha aperto il thread ha il classico problema di routine ciclica ( poi... mi sbaglierò... ). Ad ogni ciclo vorrebbe vedere la Label aggiornarsi ecc... ecc... Punto. Se è davvero tutto qui e non c'è altro, il mio consiglio è : DoEvents.

3. La soluzione targata F. Balena ( che comunque qui è superflua e l'ho tirata in ballo solo per dimostrare che si può fare eccome ciò che sostieni fosse impossibile ) per me è il miglior compromesso tra facilità di implementazione e funzionalità nei casi semplici, ripeto.
C'è chi dice "MAI DoEvents, solo multithread". Opinioni. Secondo me ci sono casi e casi...
Con tutto il rispetto che ho per voi, preferisco dare credito al consiglio di un Balena, che peraltro ho avuto modo di verificare in concreto, anche se in contrasto con quello di 10 di voi messi assieme.
MarcoGG è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 16:22   #12
CwNd
Senior Member
 
L'Avatar di CwNd
 
Iscritto dal: Jun 2007
Città: Milano
Messaggi: 413
Quote:
C'è chi dice "MAI DoEvents, solo multithread". Opinioni. Secondo me ci sono casi e casi...
C'è chi dice "non sono capace/non ho voglia di implementarlo" e c'è chi dice "mi sbatto un po' ma il risultato sarà migliore". Non è una questione d'opinione, usare un thread separato è la cosa migliore. Ti dirò di più. Sul nuovissimo Windows Market Place, se un task impiega più di un certo tempo (non ricordo precisamente quanto, comunque intorno ai 500ms) sei obbligato ad usare un thraed apposito. Pena, il tuo programma non verrà approvato per la pubblicazione.

Quote:
Con tutto il rispetto che ho per voi, preferisco dare credito al consiglio di un Balena, che peraltro ho avuto modo di verificare in concreto, anche se in contrasto con quello di 10 di voi messi assieme
Sei libero di farlo, le mie risposte era solo per farti capire il problema. Non per convincerti ad usare una soluzione piuttosto che un altra.
CwNd è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 17:02   #13
MarcoGG
Senior Member
 
L'Avatar di MarcoGG
 
Iscritto dal: Dec 2004
Messaggi: 3210
Quote:
Originariamente inviato da CwNd Guarda i messaggi
C'è chi dice "non sono capace/non ho voglia di implementarlo" e c'è chi dice "mi sbatto un po' ma il risultato sarà migliore". Non è una questione d'opinione, usare un thread separato è la cosa migliore.
C'è spesso anche chi dice "Dammi la soluzione migliore con il minor sforzo".
Personalmente ho usato parecchio il threading in .Net, e convengo che in generale sia da preferirsi. Ma non è la soluzione più veloce.
E io voglio che l'utente che ha posto la domanda sappia che esiste anche la soluzione "veloce", che nelle cose semplici è valida e funzionante. Che ci volete fare, ho la testa dura.

Ho una Form con un solo pulsante che esegue questo codice :

Codice:
        For i As Integer = 1 To 10000
            Label1.Text = i
        Next
E' già sufficiente perchè l'utente veda solo 0 ( testo Label a design ) e 10000 e nessuno dei valori intermedi.
E di casi simili a questo, certo ben più significativi, ne ho visti a centinaia.
Che faccio, consiglio il multithreading + relativa gestione del cross-thread sulla Form, come prima cosa ?
Tu dirai : SI.
Io invece dico : vediamo se è davvero una cosa veloce, al threading si fa sempre a tempo, semmai.
Quindi è QUI l'opinione, semmai, NON sul fatto che il multithreading sia o meno la scelta più corretta.

Codice:
        For i As Integer = 1 To 10000
            Label1.Text = i
            My.Application.DoEvents()
        Next
e con 1 riga hai risolto.

Più performante o meno, dato che poi comunque sta benedetta Label la devi aggiornare dall'altro Thread ? Forse un pochino... Comunque sia questa è la soluzione in assoluto più semplice, adatta ai casi semplici.
Cosa volete che vi dica : se DoEvents non vi piace, fate una petizione al Team di VS perchè venga deprecato.
MarcoGG è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 18:28   #14
voyager18
Member
 
Iscritto dal: Aug 2007
Messaggi: 138
Quote:
Originariamente inviato da MarcoGG Guarda i messaggi
Se l'operazione è bloccante e costituita da un'istruzione unica, come un download ( My.Computer.Network.DownloadFile(link, target) ), come fai ad aggiornare una Label ?
Non penso fosse l'intenzione di voyager18.
Potrei sbagliarmi, ma credo si tratti di una sua routine ciclica, da qui la mia risposta.
Il mio problema non è con una routine ciclica ma al clic di un pulsante eseguo tre istruzioni (una volta soltanto) che richiedono parecchio tempo perchè attendono la risposta da un Web Service (a volte anche 3-4 minuti).
voyager18 è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 18:30   #15
CwNd
Senior Member
 
L'Avatar di CwNd
 
Iscritto dal: Jun 2007
Città: Milano
Messaggi: 413
Prova a fare una semplice

Codice:
Thread.Sleep(3000)
dentro il codice.
La tua label sicuramente verrà aggiornata, ma la gui non risponderà agli eventi.

Quote:
Originariamente inviato da voyager18 Guarda i messaggi
Il mio problema non è con una routine ciclica ma al clic di un pulsante eseguo tre istruzioni (una volta soltanto) che richiedono parecchio tempo perchè attendono la risposta da un Web Service (a volte anche 3-4 minuti).
Nel caso possono essere così lunghe ti suggerisco di usare i metodi asincroni per fare le chiamate. Se hai generato il proxy per il webservice tramite svcutils.exe c'è un opzione per far generare le classi direttamente con qui metodi. Da visual studio basta che quando fai "aggiungi riferimento al servizio" vai su "avanzate" e spunti la casella "Genera operazioni asincrone". Usandoli sicuramente non hai problemi di freezing della gui e potrai farci qualsiasi operazione.

Ultima modifica di CwNd : 28-12-2009 alle 18:38.
CwNd è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 18:55   #16
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12093
Quote:
Originariamente inviato da voyager18 Guarda i messaggi
Il mio problema non è con una routine ciclica ma al clic di un pulsante eseguo tre istruzioni (una volta soltanto) che richiedono parecchio tempo perchè attendono la risposta da un Web Service (a volte anche 3-4 minuti).
E io direi di non bloccare il thread di gestione degli eventi durante l'esecuzione della tua applicazione perchè il tuo programma resterà bloccato, e l'effetto per l'utente finale è semplicemente quanto di peggio possa esserci imho.
Praticamente ad ogni istruzione resterà bloccato tutto aggiornandosi solo quando verrà chiamata l'Application.DoEvents() tra un'istruzione e l'altra.
La soluzione + completa per me è il backgroundworker, ma volendo anche il begininvoke col callback può andare bene, dipende dalle situazioni...
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 19:22   #17
MarcoGG
Senior Member
 
L'Avatar di MarcoGG
 
Iscritto dal: Dec 2004
Messaggi: 3210
Quote:
Originariamente inviato da voyager18 Guarda i messaggi
Il mio problema non è con una routine ciclica ma al clic di un pulsante eseguo tre istruzioni (una volta soltanto) che richiedono parecchio tempo perchè attendono la risposta da un Web Service (a volte anche 3-4 minuti).
Ecco, se lo dicevi subito mi risparmiavo sta noiosa mini-polemica.
E la Label quando la vuoi refreshare ?
E magari postare un po' di codice ?
Però mi raccomando, sempre informazioni col contagocce, sennò è troppo facile.
MarcoGG è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 21:06   #18
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12093
Quote:
Originariamente inviato da MarcoGG Guarda i messaggi
Ecco, se lo dicevi subito mi risparmiavo sta noiosa mini-polemica.
E la Label quando la vuoi refreshare ?
E magari postare un po' di codice ?
Però mi raccomando, sempre informazioni col contagocce, sennò è troppo facile.

in effetti...
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 28-12-2009, 22:08   #19
voyager18
Member
 
Iscritto dal: Aug 2007
Messaggi: 138
Ho provato con il background worker e funziona! Grazie a tutti!!
voyager18 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


HP Elitebook Ultra G1i 14 è il notebook compatto, potente e robusto HP Elitebook Ultra G1i 14 è il notebook c...
Microsoft Surface Pro 12 è il 2 in 1 più compatto e silenzioso Microsoft Surface Pro 12 è il 2 in 1 pi&u...
Recensione REDMAGIC Astra Gaming Tablet: che spettacolo di tablet! Recensione REDMAGIC Astra Gaming Tablet: che spe...
Dopo un mese, e 50 foto, cosa abbiamo capito della nuova Nintendo Switch 2 Dopo un mese, e 50 foto, cosa abbiamo capito del...
Gigabyte Aero X16 Copilot+ PC: tanta potenza non solo per l'IA Gigabyte Aero X16 Copilot+ PC: tanta potenza non...
Dick Pic addio? L'AI di Flirtini insegna...
WhoFi: riconoscimento biometrico tramite...
Zero-day SharePoint: Microsoft punta il ...
Grab & Go, il nuovo Telepass per chi...
Primo chip quantistico con elettronica e...
Da Microsoft due nuovi Surface Laptop 5G...
Processore NVIDIA N1X slittato al 2026: ...
Tesla, nel secondo semestre più a...
One UI 8 Watch arriva su Galaxy Watch Ul...
Moon Studios scarica Xbox: No Rest for t...
L'idea di JPMorgan: prestiti e finanziam...
Candy Crush: non solo il gioco! Arriva a...
Ecco come siamo riusciti a raccogliere l...
Agentic AI Framework: l'IA basata su age...
Offerte Amazon pazze di luglio: portatil...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 07:05.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v