Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    Progressbar e dati background

    Buongiorno a tutti,
    ho un dubbio su due fronti.
    1 - Ho una windows form in c# usando Visual Studio, vorrei che al click su un pulsante (Start) parta una progressbar, che si trova vicino al pulsante in loop tipo "progressBar.Style = ProgressBarStyle.Marquee" (questa non deve essere incrementale) ho già provato con backgroundworker ma mi funziona solo nel caso sia incrementale. Quello che dovrebbe fare è girare in loop finché non finisce l'esecuzione dei comandi.

    2 - Vorrei creare un loop che invii a dei label dati continui, ci sono parzialmente riuscito con backgroundworker, ma funziona solo con dati int, mentre con dati di tipo string no. Qualcuno ha già fatto una cosa del genere?

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    1) Imposta un minimo e massimo e ripeti il ciclo finché il thread non termina

    2) Non si capisce cosa vuol dire "non funziona con le stringhe" ... se non si hanno maggiori dettagli non si può indovinare ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Ciao, ti spiego meglio il punto due che è quello che mi preme di più.
    Attraverso la libreira Renci.SSH, invio un comando ad un terminale che mi restituisce un testo "string".

    codice:
    private void button_connetti_Click(object sender, EventArgs e)
            {
                String IP = textBox_ip.Text.Trim();
                Int32 Port = Int32.Parse(textBox_port.Text.Trim());
                ConnectionInfo connectionInfo = new PasswordConnectionInfo(IP, Port, username, password);
                using (SshClient client = new SshClient(connectionInfo))
    
                   try
                    {
                        if (!client.IsConnected)
                        {
                            client.Connect();
                        }
                          
                        // il mio codice per ricavare i dati e popolare i campi textbox
                    }
                    catch (Exception exp)
                    {
                        
                    }
                    finally
                    {
                        
                    }
                }
    }
    Quello che vorrei fare è far si che questo comando venga inviato ripetutamente ogni 2 secondi senza che blocchi il windows form lasciando la possibilità di utilizzare le altre funzioni.
    Per questo pensavo ad un backgroundWorker ma tutti gli esempi che trovo sono riguardanti delle progress bar.

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    E' ovvio che devi usare un thread ma non capisco perché devi cercare "esempi" da usare.

    Scrivi tu il codice che nel thread secondario, in loop, invii e riceva i dati.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Perchè sono alle prime armi ho iniziato da una settimana con c#, riesco a programmare perchè conosco altri linguaggi di programmazione ma molte dinamiche non le conosco, mi puoi spiegare come faresti te?

  6. #6
    Nessuno idea??

  7. #7
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    Ti ho detto come fare ... prova ad iniziare a scrivere il codice ... sbattici la testa. Purtroppo non ho tempo per scriverlo ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  8. #8
    Prima di tutto non mi hai dato la risposta, ma sono io che già sapevo cosa fare, l'unica cosa che avevo chiesto era una mano nel realizzarla o delle dritte, la prossima volta se non hai tempo per aiutare, non rispondere ad un forum, non serve assolutamente a niente. Grazie per niente.

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    Prima di tutto datti una calmata ...

    in secondo luogo ti ho precisato che non ho tempo per scrivere il codice, non per questo non posso rispondere e comunque non lo dici tu.

    infine ti avevo suggerito di iniziare a scrivere un loop in cui ricevi i dati ma non l'hai fatto.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  10. #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 © 2024 vBulletin Solutions, Inc. All rights reserved.