Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 15
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    59

    [C#] Due domande sui thread

    Prima domanda:
    Voglio eseguire delle funzioni usando dei thread in modo che la form non vada in blocco

    codice:
      private void button1_Click(object sender, EventArgs e)
            {
                button1.Enabled = false;
                textBox2.Text = "";
                progressBar2.Step = 1;
                progressBar2.Value = 0;
                progressBar2.Minimum = 0;
                progressBar2.Maximum = 30;
    
                progressBar1.Step = 1;
                progressBar1.Value = 0;
                progressBar1.Minimum = 0;
                progressBar1.Maximum = 800;
                if (checkBox1.Checked)
                {
                    ping();
                }
                if (checkBox2.Checked)
                {
                    traceroot();
                }
                if (checkBox3.Checked)
                {
                    int nodi = traceroot();
                    progressBar1.Maximum = (nodi*N_test);
                    thread = new Thread(new ThreadStart(pathping));
                    thread.Start();
                }
                if (checkBox4.Checked)
                {
                    thread = new Thread(new ThreadStart(download));
                    thread.Start();
                }
                button1.Enabled = true;
            }
    il fatto è che prima che quando viene seguita la funzione

    codice:
    thread = new Thread(new ThreadStart(pathping));
    la form non vada avanti ad eseguire anche

    codice:
    thread = new Thread(new ThreadStart(download));
    ho già provato con

    codice:
    thread.join();
    posto dopo l'avvio ma il comando mi blocca la form. Come posso fare??

    Seconda domanda:
    Quando il pulsante X della form viene premuto ovviamente se un altro thread è aperto mi viene dato errore. Come faccio a chuidere prima i thread e poi la form??

    Grazie a tutti.

  2. #2
    Utente di HTML.it L'avatar di ybla82
    Registrato dal
    Jan 2009
    Messaggi
    92
    ti rispondo in ordine.

    1) il meotdo .join() aspetta che il thread finisca, quindi se chiamato lì ti fermerà l'applicazione in attesa che il thread finisca...in pratica è come non usare i thread.

    Se devi evitare di entrare nell'IF successivo, non pui metterci semplicemente un return?

    2)Esiste un evento legato alla form che si chiama FormClosing.
    Il metodo che legherai a questo evento dovrà contenere le istruzioni per chiudere il thread: ad esempio thread.Abort(); (non sono sicuro che sia questa l'esatto nome del metodo, ma sicuramente qualcosa di simile)

    Ciao

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    59
    Originariamente inviato da ybla82
    ti rispondo in ordine.

    1) il meotdo .join() aspetta che il thread finisca, quindi se chiamato lì ti fermerà l'applicazione in attesa che il thread finisca...in pratica è come non usare i thread.

    Se devi evitare di entrare nell'IF successivo, non pui metterci semplicemente un return?

    2)Esiste un evento legato alla form che si chiama FormClosing.
    Il metodo che legherai a questo evento dovrà contenere le istruzioni per chiudere il thread: ad esempio thread.Abort(); (non sono sicuro che sia questa l'esatto nome del metodo, ma sicuramente qualcosa di simile)

    Ciao
    1) il fatto è che voglio che che l'operazione nell'if sucessivo venga eseguito solo dopo che la prima funzione richiamata è terminata. Praticamente queste due funzioni vanno ad agire sullo stesso textbox e se eseguite contemporaneamente il risultato è un casino. Uso poi ithread perchè non voglio che la form vada in blocco visto che il tempo impiegato è di 4-5 min

    2)Ho trovato il formclosing e c'ho inserito thread.abort() (che avevo già provato) il fatto è che mi compare un'errore :Invoke or BeginInvoke cannot be called on a control until the window handle has been created dovuto a
    codice:
    progressBar1.Invoke(new BarDelegate(UpdateBar));
    praticamente è come se l'invoke non venisse chiuso. Come faccio??

  4. #4
    Utente di HTML.it L'avatar di ybla82
    Registrato dal
    Jan 2009
    Messaggi
    92
    potresti fare così:
    nell'if del primo thread ci metti un return.

    poi all'interno del thread chiami il metodo download preceduto da if chackbox4.checked.

    In questo modo il primo thread esegue tutte e due le funzioni in ordine ( se entrambe le checkbox sono checkate), oppur eesegue solamente il secondo thread nel caso solo una checkbox sia checkata.

    Per il secondo problema prova a chiamare l'invoke sulla form stessa:
    codice:
    this..Invoke(new BarDelegate(UpdateBar));

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    59
    Originariamente inviato da ybla82
    potresti fare così:
    nell'if del primo thread ci metti un return.

    poi all'interno del thread chiami il metodo download preceduto da if chackbox4.checked.

    In questo modo il primo thread esegue tutte e due le funzioni in ordine ( se entrambe le checkbox sono checkate), oppur eesegue solamente il secondo thread nel caso solo una checkbox sia checkata.

    Per il secondo problema prova a chiamare l'invoke sulla form stessa:
    codice:
    this..Invoke(new BarDelegate(UpdateBar));
    Ho fatto come hai detto e ora il primo punto funziona. Grazie
    Il problema è il secondo perchè l'invoke non posso farlo da form perchè deve avanzare man mano che il thread secondario avanza.
    codice:
    thread = new Thread(new ThreadStart(pathping));
    thread.Start();
    Praticamente l'invoke è contenuto nel thread.

  6. #6
    Utente di HTML.it L'avatar di ybla82
    Registrato dal
    Jan 2009
    Messaggi
    92
    guarda che la progressBar mantiene comunque il comportamento che gli hai dato.


    tu prova a chiamare l'invoke dalla form e poi fammi sapere se cambia qualcosa nel comportametno, ed eventualmente come

  7. #7
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    59
    SE la metto in

    codice:
    public Form1()
            {
                InitializeComponent();
                progressBar1.Invoke(new BarDelegate(UpdateBar));
            }
    mi viene dato subito l'errore:
    Invoke or BeginInvoke cannot be called on a control until the window handle has been created.

    Ti posto il codice così capisci meglio. La funzione pathping funziona così:

    Viene chiamata dal pulsante:
    codice:
    private void button1_Click(object sender, EventArgs e)
            {
                progressBar1.Step = 1;
                progressBar1.Value = 0;
                progressBar1.Minimum = 0;
                progressBar1.Maximum = 1000;
                .......
                else if (checkBox3.Checked)
                {
                    thread = new Thread(delegate() {pathping();});
                    thread.Start();
                }
    }
    si avvia quindi pathping che è creata per fare lo stesso di pathping.exe

    codice:
     private void pathping()
            {
                IPAddress ipAddress = Dns.GetHostEntry(textBox1.Text).AddressList[0];
                using (Ping pingSender = new Ping())
                {
                    //setto parametri per connessione            
                    PingOptions pingOptions = new PingOptions();
                    PingOptions pingOptions1 = new PingOptions();
                    Stopwatch stopWatch = new Stopwatch();
                    string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
                    byte[] buffer = Encoding.ASCII.GetBytes(data);
                    //byte[] bytes = new byte[32];
                    pingOptions.DontFragment = true;
                    pingOptions.Ttl = 1;
                    pingOptions1.DontFragment = true;
                    pingOptions1.Ttl = 30;
                    int maxHops = 30;
                    //scrivo su textbox
                    textBox2.BeginInvoke(new UpdateTextCallback(SetText), new object[] { "Pathping to " + ipAddress + "  over a maximum of hops:" + maxHops +  "\r\n" });
                    for (int i = 1; i < maxHops + 1; i++)
                    {
                        long tempo = 0;
                        int error = 0;
                        textBox2.BeginInvoke(new UpdateTextCallback(SetText), new object[] { i + ": " });
                        //trovo l' indirizzo IP numero n tramite il TTL
                        PingReply pingReply = pingSender.Send(ipAddress,5000, buffer, pingOptions);
                        //lo scrivo su una label
                        label1.BeginInvoke(new UpdateLabel(SetLabel1), new object[] { ipAddress.ToString() });
                        //per tot volte faccio il ping verso l' indirizzo trovato sopra 
                        for (int k = 0; k < N_test; k++)
                        {
                            System.Threading.Thread.Sleep(100);
                            //Qui il problema che si presenta che richiama la funzione sotto !!!!!!!!!! <<<<<<----------------
                            progressBar1.Invoke(new BarDelegate(UpdateBar));
                            PingReply pingReply1 = pingSender.Send(pingReply.Address, 3000, buffer, pingOptions1);
                            if (!object.Equals(pingReply1.Status,IPStatus.Success))
                            {
                                error++;
                            }
                            textBox3.BeginInvoke(new UpdateTextCallback(SetText2), new object[] { k + " verso ip " + pingReply1.Address + " tempo " + pingReply1.RoundtripTime + " ms  ttl: " + pingOptions.Ttl + " stato " + pingReply1.Status + "\r\n" });
                            tempo = tempo + pingReply1.RoundtripTime;
                            System.Threading.Thread.Sleep(500);
                        }
                        textBox2.BeginInvoke(new UpdateTextCallback(SetText), new object[] { " tempo medio " + (tempo / N_test) + "ms  da indirizzo " + pingReply.Address + " pacchetti persi " + error + "\r\n" });
                        if (pingReply.Address.ToString() == ipAddress.ToString())
                            {
                                break;
                            }
                        
                        pingOptions.Ttl++;
                    }
                }
                if (checkBox4.Checked)
                {
                    download();
                }
            }
    ed ecco qui la funzione richiamata:

    codice:
    private void UpdateBar()
            {
                progressBar1.Value++;
            }

  8. #8
    Utente di HTML.it L'avatar di ybla82
    Registrato dal
    Jan 2009
    Messaggi
    92
    perchè la dovresti mettere nel costruttore della form!?!?!!?!?!

    semplicemente sostituisci progressbar1.Invoke
    con this.Invoke nel punto in cui fa casino.

    Fammi poi sapere cosa succede

  9. #9
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    59
    Se metto this..... mi restituisce sempre l'errore :
    Invoke or BeginInvoke cannot be called on a control until the window handle has been created.

    Ps: se può essere di aiuto la chiusura della form avvienecosì:
    codice:
     private void Form1_FormClosing(Object sender, FormClosingEventArgs e)
            {
                thread.Abort();
            }

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    59
    Sto pensando di abbandonare il multi - thread ed inserire
    Application.DoEvents()
    nelle varie funzioni. Così funziona in modo semplice.

    PS: niente il processo se esegue il pathping e lo chiudo continua anche togliendo il multi-thread.

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.