2010-02-10 13 views
7

I Googled per questo e leggere alcuni thread qui, ma non ho trovato un modo semplice per avere un sonno applicazione VB.Net per un po 'e ancora mantenere l'applicazione reattiva:Modo semplice e non bloccante per dormire?

Imports System.Net 
Imports System.IO 
Imports System.Text 
Imports System.Text.RegularExpressions 
Imports System.Threading.Thread 

[...] 

''#How to keep screen frop freezing? 
While True 
    ListBox1.Items.Clear() 

    ListBox1.Items.Add("blah") 

    ''#Not much difference 
    ListBox1.Refresh() 

    ''#Wait 1mn 
    Sleep(60000) 
End While 

c'è davvero nessuna soluzione semplice e non bloccante per avere un'applicazione VB.Net in attesa per qualche secondo?

Grazie.

+1

Qual è lo scopo del sonno? O vuoi che dorma, o vuoi che sia reattivo. Se quello che stai cercando di fare è qualcosa che si verifica a intervalli programmati, quindi dillo. – dbasnett

+0

Sto raschiando una pagina web ogni minuto e vorrei che l'applicazione si fermasse ogni minuto senza il blocco della schermata dell'applicazione. Va ancora bene usare DoEvents o si consiglia di usare un timer? – Gulbahar

+0

@OverTheRainbow - Vedere il commento di Nikie qui sotto. Sembra che tu stia meglio con un timer. –

risposta

7

È questo WinForms o WPF?

Se si tratta di WinForms, è possibile utilizzare un timer anziché un ciclo while. Quindi la tua app sarà ancora reattiva e aumenterà gli eventi.

In WPF penso che dovresti creare il tuo timer basato sullo DispatchTimer class.

+0

Non ci sono anche timer in WPF? – CoderDennis

+0

Ho appena aperto un progetto molto velocemente e non ho visto alcun comando Timer nel designer, quindi potrebbe esserci molto, non ho mai avuto bisogno di usarne uno in WPF. Una rapida ricerca su google mi fa pensare che non è disponibile (http://social.msdn.microsoft.com/forums/en-US/wpf/thread/aaffea95-e735-492d-bd8a-2fdf7099a936/). –

+0

Non deve essere un controllo vero? È possibile utilizzare System.Timers.Timer o System.Threading.Timer nel codice. – ryadavilli

2

Il suggerimento del timer è davvero il modo migliore per farlo. Ma se DoEvents funziona ancora (non ho fatto VB dal 5.0), si può fare questo:

For i = 0 To 600 
    DoEvents 
    Sleep(100) 
Next 

Questo farebbe 600 posti letto di 0,1 secondi ciascuna, con un DoEvents tra ogni per gestire gli eventi attuali. Il secondo .1 dovrebbe essere un buon compromesso tra la reattività (gli eventi vengono gestiti entro 0,1 secondi) e il consumo della CPU (fallo troppo velocemente e l'app inizierà a consumare una quantità significativa di tempo CPU anche durante l'attesa).

+0

Dear downvoter, mentre accetto rispettosamente il tuo downvote, considereresti di lasciare un commento con cui potrei migliorare la mia risposta? Grazie. – Wim

+0

Non so perché sia ​​stato downvoted. Le funzioni sono chiamate Application.DoEvents e Thread.Sleep in .NET, ma chiunque abbia un MSDN aggiornato lo avrebbe scoperto. Va sottolineato che DoEvents può portare a tutti i tipi di comportamenti strani (ad esempio se il modulo è chiuso mentre la funzione è in esecuzione o se DoEvents chiama di nuovo la stessa funzione.) Ma hai detto che non è il modo ideale per farlo . – Niki

+1

Non sono il downvoter, ma DoEvents non è una buona pratica. Causa problemi se il metodo non è stato scritto correttamente per tenere conto del rientro. –

7
Public Sub ResponsiveSleep(ByRef iMilliSeconds As Integer) 
    Dim i As Integer, iHalfSeconds As Integer = iMilliSeconds/500 
    For i = 1 To iHalfSeconds 
     Threading.Thread.Sleep(500) : Application.DoEvents() 
    Next i 
End Sub 

Chiama ResponsiveSleep per mettere in pausa un particolare pezzo di codice mantenendo l'applicazione abbastanza reattiva. Per rendere l'applicazione più iHalfSeconds sensibili potrebbero essere modificati per decimi o centesimi di secondo

+1

Questo metodo utilizzava meno risorse della CPU rispetto al cronometro. – rsrobbins

+2

Ho avuto problemi con 'Application.DoEvents()'. Vedi [qui] (https://social.msdn.microsoft.com/Forums/vstudio/en-US/48b4a763-7387-46da-8fc2-3e885670f62c/the-undo-operation-encounted-a-context-that-is -differente? forum = netfxbcl), per esempio. – pelesl

+0

è che ':' costruisce qualcosa di specifico per VB? Come apparirebbe in C#? – Nyerguds

4
Private Sub wait(ByVal interval As Integer) 
    Dim stopW As New Stopwatch 
    stopW.Start() 
    Do While stopW.ElapsedMilliseconds < interval 
     ' Allows your UI to remain responsive 
     Application.DoEvents() 
    Loop 
    stopW.Stop() 
End Sub 
2

In realtà, la soluzione è duplice: 1.) Utilizzare un timer invece di dormire, dormire fa come si dice, le cause il filo per dormire 2.) Utilizzare il multithreading e far funzionare la funzione di screen scrap nella propria thread, migliorando notevolmente la reattività dell'applicazione.

Threading.Thread.Sleep(IntSleepTime) 

è una funzione di sonno thread-safe che mettere in pausa il thread corrente per il tempo specificato, quindi se si sceglie di usare il sonno, è possibile farlo in un ambiente multi-threading e manterrà il resto della tua App reattiva perché stai dormendo solo una discussione ramificata, non il thread principale.

0

U fare il thread dell'interfaccia utente che consegna il modulo a dormire. Se vuoi rendere l'applicazione reattiva, prima crea un metodo che aggiunge gli elementi nella visualizzazione elenco e quando i carichi del modulo vengono avviati usando il thread, ora usa sleep per rendere il thread di visualizzazione della lista sleep e ur sarà in risposta stato ..

0

Questo è per VB non VBA

Private Async Function PauseTime(ByVal MS As Integer) As Task 

    Await Task.Run(Sub()       
          Thread.Sleep(MS) 

        End Sub) 


    End Function