2010-01-22 14 views
6

Ho un'applicazione che esegue il ping di ogni possibile IP sulla subnet locale per compilare un elenco di indirizzi IP reattivi. Attualmente esegue il ping di tutti i 255 uno alla volta. È possibile convertire questa app per utilizzare più thread per aumentare la velocità eseguendo il ping di più di uno alla volta? Sono nuovo del concetto di più thread e penso che questo sia un buon modo per imparare (finché è possibile, naturalmente).Convertire l'applicazione Ping nella versione con multithreading per aumentare la velocità - C#

inoltre, qualsiasi miglioramento stilistico su cui puoi educarmi sarebbe anche utile.

grazie in anticipo

Ecco il metodo ping corrente in un evento backgroundWorker1_DoWork.

 private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
      count = 0; 
      for (int i = 1; i < 255; i++) 
      { 
       Ping ping = new Ping(); 
       PingReply pingreply = ping.Send(IPAddress.Parse(locip[0] + "." + locip[1] + "." + locip[2] + "." + i)); 
       count += 1; 

       if (pingreply.Status == IPStatus.Success) 
       { 
        status = "o"; 
        repAddress = pingreply.Address.ToString(); ; 
        repRoundtrip = pingreply.RoundtripTime.ToString(); 
        repTTL = pingreply.Options.Ttl.ToString(); 
        repBuffer = pingreply.Buffer.Length.ToString(); 
        string[] lineBuffer = { status, repAddress, repRoundtrip, repTTL, repBuffer }; 
        ipList.Rows.Add(lineBuffer); 

       } 
        progressBar.Invoke(new MethodInvoker(UpdateProgressBarByOne)); 
        progressStatus.Text = ("Pinging IP " + count + " of 254"); 

      } 
      button1.Enabled = true; 
      progressBar.Invoke(new MethodInvoker(ResetProgressBar)); 

    } 

risposta

2

Sembra che Ping abbia una funzione SendAsync. This post (ne conosco il vb, ma solo per farsi un'idea) ha un esempio. In sintesi, basta cambiare il vostro invio per SendAsync e ascoltare l'evento PingCompleted

1

Beh il mio consiglio è quello di esaminare i punti di concorrenza.

In primo luogo si verifica un errore con qualsiasi accesso a oggetti di Windows Form fuori dal thread. Il tuo accesso al pulsante 1 Lancia un MDA nel debug e potrebbe bloccarsi in modo casuale al runtime. Devi usare un delegato e richiamare il metodo sul thread principale usando un pattern come questo.

this.Invoke(delgatetomyupdatermethod) 

In secondo luogo, il tempo è trascorso nel ping stesso. Quindi mi sento di raccomandare a scrivere un elenco threadsafe (basta scrivere un metodo con un blocco su di esso

private object locker = new object(); 

private void InsertIntoList(string linebuffer) 
{ 
    lock(locker) 
    { 
     ipList.Rows.Add(linebuffer); 
    } 
} 

mi consiglia di utilizzare il ThreadPool Net per eseguire il metodo, invece di eseguire il ping di un determinato IP.

Per fare scrivere una funzione che eseguirà l'IP per eseguire il ping e aggiornare l'elenco con il risultato, quindi chiamarlo accodando gli elementi sul threadpool, infatti se passi un oggetto con un oggetto ManualResetEvent puoi persino scrivere il tuo codice per dire

System.Threading.WaitHandle[] waits = new System.Threading.WaitHandle[255]; 
//initialise the list of these and create the objects to ping. 


foreach (var obj in mylistofobjectvalues) 
{ 
    System.Threading.Threadpool.QueueUserWorkItem(method, obj); 
} 
System.Threading.WaitHandle.WaitAll(waits); 

cui metodo è il ping metodo, obj contiene un oggetto con manualresetevent e informazioni che il metodo deve eseguire il ping della sua destinazione.

Ogni volta che il tuo waithandle completa, puoi aggiornare il tuo stato. Con un po 'più di sforzo sulla tua GUI, potresti persino far funzionare il sistema in modo asincrono, in modo che il tuo gui venga aggiornato su ogni risposta, non solo alla fine.

+0

Sono sicuro che questo ha senso, non ho idea di cosa dice, lol. Scusate se sono un rimedio, questa soluzione è finita in testa, il che probabilmente significa che anche la mia domanda è finita. – user48202

+0

come passare un argomento durante il richiamo di un metodo come questo ipList.Invoke (new MethodInvoker (UpdateIpList (lineBuffer))); Continua a dirmi "UpdateIpList (lineBuffer)" non è un metodo. – user48202

+0

I moduli e i thread di Windows non sono facili da fare. stessa cosa con la concorrenza, ci vuole un po 'di apprendimento per farlo bene. Consiglio vivamente di "Programmare Visual C# 2008 la libreria di classi base" che ha una buona intro introduzione (e anche tutte le parti buone del framework). – Spence

Problemi correlati