2010-01-22 17 views
6

Tengo una aplicación que hace ping a cada IP posible en su subred local para compilar una lista de direcciones IP receptivas. Actualmente hace ping all 255 uno a la vez. ¿Es posible convertir esta aplicación para usar varios hilos para aumentar la velocidad haciendo ping a más de uno a la vez? Soy nuevo en el concepto de múltiples hilos y creo que esta sería una buena forma de aprender (siempre que sea posible, por supuesto).Convertir la aplicación de ping a la versión multiproceso para aumentar la velocidad - C#

también, cualquier mejora estilística que pueda enseñarme también sería útil.

gracias de antemano

Aquí está el método de ping actual en 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)); 

    } 

Respuesta

2

Parece que Ping tiene una función SendAsync. This publicación (sé que es vb, pero solo para tener una idea) tiene un ejemplo. En resumen, solo cambie su Send to SendAsync y escuche el evento PingCompleted

1

Bueno, mi consejo es buscar en sus puntos de concurrencia.

En primer lugar, se golpea un error con cualquier acceso a los formularios de Windows objetos fuera del hilo. es decir, su acceso al botón 1 arrojará un MDA en la depuración, y puede bloquearse en el tiempo de ejecución al azar. Tienes que usar un delegado e invocar el método en el hilo principal usando un patrón como este.

this.Invoke(delgatetomyupdatermethod) 

En segundo lugar, su tiempo se gasta en el ping. Por lo que recomiendo escribir una lista multi-hilo (acaba de escribir un método con un bloqueo en ella

private object locker = new object(); 

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

yo recomendaría usar el threadpool .Net para ejecutar su método en lugar de hacer ping a una determinada IP.

Para hacer esto escribe una función que tomará en el IP para hacer ping y actualizar la lista con su resultado, luego llamarlo haciendo cola en los elementos en el grupo de hilos. De hecho, si pasa un objeto con un ManualResetEvent, incluso puede escribir su código para decir

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); 

donde el método es el ping método, obj contiene un objeto con el evento manual e información que su método necesita para hacer ping a su objetivo.

Cada vez que finalice su waithandle puede actualizar su estado. Con un poco más de esfuerzo en su GUI, incluso podría hacer que el sistema funcione de manera asíncrona, de modo que su GUI se actualice en cada respuesta, no solo al final.

+0

Estoy seguro de que esto tiene todo el sentido, simplemente no tengo ni idea de lo que dice, jajaja. Lo siento si soy un remedio, esta solución está por encima de mi cabeza, lo que probablemente significa que mi pregunta también está por encima de mi cabeza. – user48202

+0

cómo paso un argumento al invocar un método como este ipList.Invoke (new MethodInvoker (UpdateIpList (lineBuffer))); Me sigue diciendo que "UpdateIpList (lineBuffer)" no es un método. – user48202

+0

Las formas e hilos de Windows no son fáciles de hacer. Lo mismo con la concurrencia, se necesita un poco de aprendizaje para hacerlo bien. Recomiendo mucho "Programming Visual C# 2008 la biblioteca de clases base", que tiene una gran introducción al enhebrado (y todas las partes buenas del framework también). – Spence

Cuestiones relacionadas