Può uno Sleep in un Timers.Timer bloccare l' output del programma?

di il
5 risposte

Può uno Sleep in un Timers.Timer bloccare l' output del programma?

Mi spiego meglio... per andare a trovare dove un mio programmino si "impunta" per microsecondi (esempio nell' aprire qualche finestra o muoverla o selezionare qualche opzione) ho deselezionato qui e là finché ho visto che il problema è in questo semplicissimo codice:
    Private Sub Timer_ReadPixels_Elapsed(sender As Object, e As Timers.ElapsedEventArgs) Handles Timer_ReadPixels.Elapsed
        FaiQuesto1()  'leggerissimo
        Beep()        
        Sleep(300)
        FaiQuesto2()  'leggerissimo
    End Sub        
Il Timer è settato su 5 secondi: se muovo velocemente sul monitor una qualsiasi delle finestre del programma (esempio il FormInfo) questa si blocca esattamente quando suona il Beep (a significare che si blocca quando si arriva allo Sleep(), che è lo scopo del Beep() di Debug), mentre il puntatore va avanti... dopo microsecondi la finestra lo raggiunge.

Se elimino il Beep() la Finestra si blocca ugualmente, se elimino lo Sleep(300)... gira come una trottola senza interruzioni.

Eppure ho bisogno di "distanziare" un attimino le due Sub... c' è modo di farlo senza "impuntare" il programma e perché si impunta?? Il Timer è nel FormMain, ma si blocca per microsecondi qualsiasi altra finestra aperta.

NOTA: il Timer è un System.Timers.Timer, quindi dovrebbe essere un Timer di Thread...

5 Risposte

  • Re: Può uno Sleep in un Timers.Timer bloccare l' output del programma?

    Non si è capito molto, ma potresti lanciare un secondo timer, dopo FaiQuesto1(), che fa l'elapsed dopo 300 ms, esegue FaiQuesto2() e poi si stoppa da solo
  • Re: Può uno Sleep in un Timers.Timer bloccare l' output del programma?

    Il consiglio di Weierstrass è il più semplice ed intuitivo, non mi sembra che serva aggiungere altro.
    Invece scrivo perché ho notato che ti sembra di aver trovato un'anomalia e ritieni che il codice non faccia quello che ti aspettavi.
    L'istruzione Sleep(300), ferma per 300 millisecondi il programma senza occupare CPU. Questo significa che l'istruzione successiva non verrà eseguita prima che sia trascorso il tempo impostato su Sleep. Devi sapere che mentre il codice è in esecuzione Sleep o non Sleep, l'interfaccia grafica non viene aggiornata, perché il codice grava su un unico Thread, nulla viene eseguito in parallelo, tutto avviene sequenzialmente, i Timer danno una parvenza di parallelismo ma in realtà così non è.
    Se vuoi usare più Thread o fare in modo che parte del codice venga eseguito in modo asincrono devi studiare: BackgroundWorker in System.ComponentModel, oppure Thread in System.Threading.Thread, in ultimo, Async Await.
    Tutti sono validi, ma presentano difficoltà diverse di apprendimento.
  • Re: Può uno Sleep in un Timers.Timer bloccare l' output del programma?

    Direi che Weierstrass e Rubik ti hanno risposto più che bene, niente da aggiungere.

    Se vuoi provare puoi usare la routine che ti scrivo di seguito al posto dello Sleep che usi tu, vedi se risolvi il problema, ma ripeto non sarebbe la soluzione corretta
        Public Sub MioSleep(ByVal MilliSeconds As Integer)
    
            Application.DoEvents()
            Dim sw = Stopwatch.StartNew
            Do Until sw.ElapsedMilliseconds >= MilliSeconds
                Threading.Thread.Sleep(10)
                Application.DoEvents()
            Loop
            sw.Stop()
    
        End Sub
    
  • Re: Può uno Sleep in un Timers.Timer bloccare l' output del programma?

    Grazie per le risposte.
    Ho risolto eseguendo il codice su un altro Thread, cosa che, a leggere la documentazione di Microsoft, avrebbe GIA' dovuto fare il Timers.Timer a differenza del Forms.Timer.
  • Re: Può uno Sleep in un Timers.Timer bloccare l' output del programma?

    phil2000 ha scritto:


    Grazie per le risposte.
    Ho risolto eseguendo il codice su un altro Thread, cosa che, a leggere la documentazione di Microsoft, avrebbe GIA' dovuto fare il Timers.Timer a differenza del Forms.Timer.
    Attento a non confondere i vari Timer, ce ne sono parecchi:
    .NET includes several timer classes, each of which offers different functionality:

    System.Timers.Timer, which fires an event and executes the code in one or more event sinks at regular intervals. The class is intended for use as a server-based or service component in a multithreaded environment; it has no user interface and is not visible at runtime.

    System.Threading.Timer, which executes a single callback method on a thread pool thread at regular intervals. The callback method is defined when the timer is instantiated and cannot be changed. Like the System.Timers.Timer class, this class is intended for use as a server-based or service component in a multithreaded environment; it has no user interface and is not visible at runtime.

    System.Windows.Forms.Timer, a Windows Forms component that fires an event and executes the code in one or more event sinks at regular intervals. The component has no user interface and is designed for use in a single-threaded environment; it executes on the UI thread.

    System.Web.UI.Timer (.NET Framework only), an ASP.NET component that performs asynchronous or synchronous web page postbacks at a regular interval.

    System.Windows.Threading.DispatcherTimer, a timer that's integrated into the Dispatcher queue. This timer is processed with a specified priority at a specified time interval.
    Lascio anche il link alla fonte

    Per il Timer asincrono devi usare quello linkato creando il callback. In alternativa, puoi usare il primo ma gestisci tu il thread su cui farlo lavorare. Per il Form.Timer è specificato che l'uso è single-thread (più precisamente quello dell'UI).
Devi accedere o registrarti per scrivere nel forum
5 risposte