Home Page
Articoli
Tips & Tricks
News
Forum
Archivio Forum
Blogs
Sondaggi
Rss
Video
Utenti
Chi Siamo
Contattaci
Username:
Password:
Login
Registrati ora!
Recupera Password
Home Page
Stanze Forum
App. WinForms / WPF .NET
Leggere un file di testo asincronamente ed aggiornare un textbox
venerdì 25 luglio 2008 - 13.46
Elenco Threads
Stanze Forum
Aggiungi ai Preferiti
Cerca nel forum
intelinside
Profilo
| Newbie
4
messaggi | Data Invio:
ven 25 lug 2008 - 13:46
Salve,
devo implementare un sistema per cui leggendo un file da disco questi viene mostrato in realtime in un form con textbox.
Ho creato una classe che tramite IEnumerable ed un thread mentre legge riga per riga il file richiama attraverso un delegato il metodo di aggiornamento del form che contiene il textbox che mostrerà il file.
Ovviamente accade che pur se in background la UI sembra 'bloccata' immagino perche la message pump di tutti gli invoke fatti dall'altro thread finiscono per bloccare comunque il form che contiene il textbox multiline.
Ora, potrei leggere tutto il file in background ed alla fine mostrarlo ma possibile che non esiste un modo per far aggiornare il textbox mentre si legge il file ?
(ad onor del vero mettendo un Threading.Thread.Sleep(100) nelle fasi cicliche di reperimento dati c'è un miglioramento ma comunque è inaccettabile)
Grazie dei consigli
Lanello
Profilo
| Senior Member
218
messaggi | Data Invio:
ven 25 lug 2008 - 14:40
nella tua funzione di aggiornamento del textbox prova con un "banale"
Application.Doevents()
non è molto "stilosa" come soluzione, ma permette alla tua application di eseguire tutte le operazioni di ridisegno che ti permette di non avere quell'effetto "blocco" che stai verificando.
Facci sapere ;)
-----------------------------------------------------
La ricompensa per una cosa ben fatta, è averla fatta.
intelinside
Profilo
| Newbie
4
messaggi | Data Invio:
ven 25 lug 2008 - 15:26
Si ho provato con Application.Doevents(), ma come dicevi non è la soluzione stilistica migliore.
Lo scenario è che ho una classe che attraverso questo metodo
Private Sub StartCollect()
Dim SB As New Text.StringBuilder(1000), localCounter As Integer
Do
SB.Append(DirectCast(InnerIEnumerableClass.GetEnumerator, IEnumerator(Of String)).Current & ControlChars.CrLf)
localCounter += 1
If localCounter >= LineBuffer Then
GuiDelegate(SB.ToString)
SB.Remove(0, SB.Length)
End If
Loop Until Not CType(InnerIEnumerableClass.GetEnumerator, IEnumerator).MoveNext
If SB.Length > 0 Then GuiDelegate(SB.ToString)
End Sub
End Class
richiamato da un thread invoca il delegato GUIDELEGATE ogni 100 righe lette (in effetti viene letta riga x riga nel MoveNext dell'interfaccia IEnumerator dell'oggetto InnerIEnumerableClass).
Nell'applicazion Winform che consuma questa classe avviene il marshaling:
Private Sub UIUpdateMethod(ByVal m As String)
If TextBox1.InvokeRequired Then
TextBox1.Invoke(New MultithreadReader.GUIUpdater(AddressOf UIUpdateMethod), m)
Else
TextBox1.Text &= m.ToString & ControlChars.CrLf
'Application.DoEvents()
End If
End Sub
Effettivamente mettendo il DoEvents() tutto fila liscio ma è corretto tutto ciò ? Non si dovrebbe evitare il DoEvents ?
Grazie per i consigli
Lanello
Profilo
| Senior Member
218
messaggi | Data Invio:
ven 25 lug 2008 - 15:39
ho dato una rapida occhiata al tuo codice, ma lavori con files di testo o binari???
perchè mi pare che ti stai complicando un po la vita....
comunque a parte questo...
il comando
Application.DoEvents()
non è ERRATO, è soltanto uno strumento del .NET che indica alla tua Application di svuotare la coda delle istruzioni da eseguire, comprese quelle intrinseche di ridisegno delle interfacce.
quindi non è Errata, è solo poco "stilosa".
se te la fai da solo, facendo "girare" solo le operazioni che ti servono strettamente senza far svuotare la coda delle istruzioni all'applicazione riesci ad ottenere prestazioni migliori.
ma se il metodo ti risolve il problema senza grossi rallentamenti non vedo perchè "infognarsi" in un problema più grosso di te.
vedi
http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx
per i riferimenti al metodo doevents.
-----------------------------------------------------
La ricompensa per una cosa ben fatta, è averla fatta.
intelinside
Profilo
| Newbie
4
messaggi | Data Invio:
ven 25 lug 2008 - 16:02
Ciao grazie per le risposte.
Il mio codice è un codice di test, non un caso reale.
In pratica avevo progettatto una classe che definendo nel new un file di testo ed un buffer di righe da leggere questa avvolga all'interno un oggetto IEnumerable ed un IEnumerator(of String) in modo che si potesse ciclare le righe del file senza obbligatoriamente mettere tutto il contenuto in memoria.
Quindi nel movenext di IEnumerator legge la riga seguente e prospone in current la riga letta.
Nella classe principale c'è un metodo sincrono che espone l'enumeratore e c'è un metodo asincrono che tramite un thread cicla il file per ogni N righe richiamando l'invoke di un delegato che deve essere puntato ad una routine nel form o assembly ospitante la classe.
Inizialmente la routine che serviva il delegato era la scrittura dello stesso file in 'background' in una windows application poi nel test di visualizzazione mi sono dovuto fermare per il blocco della UI (che in caso di scrittura file invece non avveniva).
Comunque solo con Dovents() in effetti si ha un UI decentemente utilizzabile.
Grazie dei consigli
Torna su
Stanze Forum
Elenco Threads
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 !