Visualizzazione dei risultati da 1 a 10 su 10

Visualizzazione discussione

  1. #10
    Utente di HTML.it
    Registrato dal
    Jul 2015
    Messaggi
    57
    Hai diverse possibilità per fare quello che vuoi, ad esempio:

    se vuoi mandare dati ogni "tot" secondi puoi usare un Timer, ti consiglio della libreria

    codice:
    using System.Timers;
    lo inizializzi quando la finestra è pronta

    codice:
    private System.Timers.Timer m_Timer;
    
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
      m_Timer = new System.Timers.Timer();
      m_Timer.Elapsed += Timer_Elapsed;
      m_Timer.Interval = 4000; // in millisecondi
    }
    e lo fai partire quando lo ritieni più opportuno

    codice:
      m_Timer.Start();
    la funzione associata all'evento Elapsed definita da te viene richiamata ogni "interval" tempo
    questa funzione è in parallelo al thread principale dell'applicazione e quindi dell'UI pertanto è non bloccante.

    codice:
    private void Timer_Elapsed(object sender, ElapsedEventArgs e)
    {
      // scrivi il codice da svolgere ogni "interval" tempo.
    }
    Ricordati anche di fermare il timer quando termini le operazioni.

    codice:
    protected override void OnClosing(CancelEventArgs e)
    {
      m_Timer.Stop();
      m_Timer.Dispose();
      base.OnClosing(e);
    }
    chiaramente utilizzando un thread devi stare attento a non far collidere le informazioni tra di loro, ad esempio se la tua funzione impiegasse di più di 4 secondi a svolgersi, rischi di avere conflitti di operazioni e quindi variabili non coerenti, devi decidere te come gestire il fatto.

    per il fatto della barra di progressione, se la marchi indeterminata, cioè rappresentata dalla linea che scorre all'infinito, ti basta semplicemente all'inizio della funzione Timer_Elapsed renderla visibile, ed al termine la nasconderla nuovamente, anche qui devi stare attento alla manipolazione di controlli di interfaccia che non appartengo al Timer ma bensì al Dispacher dell'applicativo.

    oppure come hai optato

    il BackgroundWorker è un altro tipo di thread ad eventi

    codice:
    private BackgroundWorker m_Worker;
    
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
      m_Worker = new BackgroundWorker();
      m_Worker.DoWork += Worker_DoWork; // definisci cosa fare in asincrono
      m_Worker.ProgressChanged += Worker_ProgressChanged; // definisci cosa fare al richiamo di m_Worker.ReportProgress(int)
      m_Worker.RunWorkerCompleted += Worker_RunWorkerCompleted; // richiamato al termine della vita del thread
      m_Worker.WorkerSupportsCancellation = true; // supporta la cancellazione
      m_Worker.WorkerReportsProgress = true; // supporta la progressione
    }
    se la questione che avevi citato prima del fatto che il Worker.ReportProgress permette solo un dato di tipo int è perchè concettualmente
    il valore di progressione della barra è un numero intero, nulla ti impedisce che quando è arrivato il valore lo trasformi in stringa e ci applichi ad esempio la percentuale.
    Questo implica però che la barra sia realmente in progressione e non indeterminata, nel secondo caso non ti serve gestire questo evento.

    Potresti fare un BackgroundWorker con un DoWork infinito (while(true)) all'interno (più simile a Java) e metterlo in sleep ogni "tot" secondi con
    codice:
    Thread.Sleep(4000) // in millisecondi
    anche se per l'SO implica lavoro aggiuntivo.

    inoltre, in questo caso, devi anche abilitarne la cancellazione che gestirai tramite
    codice:
    if ((Worker.CancellationPending == true))
    {
      e.Cancel = true;
      break; // uscire dall'eventuale (while(true))
    }
    con il comando
    codice:
    m_Worker.CancelAsync();
    un altra alternativa, chiaramente se il tuo progetto si basa sul Framework 4.5 o superiore e l'utilizzo di async e await con la gestione Task, "thread", consigliati rispetto a BackgroundWorker.

    se vuoi approfondire, cmq richiede un po' di conoscenza nel linguaggio c#:
    https://msdn.microsoft.com/it-it/library/hh191443.aspx

    codice:
    protected async void StartLoop()
    {
      await Task.Run(() => DoWork());
    }
    
    protected void DoWork()
    {
      while (true)
      {
        // scrivi il codice da svolgere ogni ciclo.
      }
    }
    chiaramente anche in questo caso devi darli tu i tempo di esecuzione, devi proteggere l'accesso ai componenti UI, anche se puoi evitare posizionando bene il codice, comunque il vantaggio concreto è che non devi preoccuparti dell'accesso alle variabili in conflitto e non devi preoccuparti per l'accumulo di eventuali altri thread essendo gestiti da un threadpool.

    in questo caso per le attese puoi usare
    codice:
      await Task.Delay(1000);
    Queste presentate sono alcune possibilità, puoi trovarne altre, tutto dipende da quale è il compito generale dell'applicativo, ti conviene provarle tutte, verificare quale rispecchia di più le tue esigenze e di conseguenza utilizzarla nel modo più appropriato.
    Ultima modifica di Marsh; 07-11-2015 a 14:38

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.