• Domingo 22 de Diciembre de 2024, 20:00

Autor Tema:  PingException  (Leído 1663 veces)

Vixente

  • Nuevo Miembro
  • *
  • Mensajes: 2
    • Ver Perfil
PingException
« en: Jueves 4 de Marzo de 2010, 23:11 »
0
Hola a todos, ando haciendo un programita para el curro muy sencillo, que básicamente lo que hace es hacer ping a diversos servidores. Estoy empezando con el C# (vengo de C) y todo va bien, aunque he topado con las excepciones y basandome en lo que he leído y visto en ejemplos, la cosa se controla con try() y catch(). Tengo ya puesto todo como lo he visto en los ejemplos, pero el programa se ejecuta sin aparecerme la form (esta solo aparece al final). En el debugger, cuando corre el programa, veo como van saliendo las excepciones de cada ping y hasta que no termina con todos no aparece la form.

Os dejo el cacho de código importante del programa, para que me aconsejéis:
 
Código: C#
  1. Ping prueba = new Ping();
  2.            
  3.             foreach(string a in lista)
  4.             {
  5.                 pantalla.Text += lista[i];
  6.                 pantalla.Text += "...";
  7.                
  8.                 try
  9.                
  10.                 {
  11.                     PingReply respuesta = prueba.Send(lista[i], 100);
  12.                         if (respuesta.Status == IPStatus.Success)
  13.                         {
  14.                             pantalla.Text += "OK";
  15.                         }
  16.                         else
  17.                         {
  18.                             pantalla.Text += "error!";
  19.                         }
  20.                    
  21.                    
  22.  
  23.                 }
  24.                 catch (PingException ex)
  25.                 {
  26.                     pantalla.Text += ex.InnerException.Message;
  27.                 }
  28.                
  29.                 pantalla.Text += Environment.NewLine;
  30.                 i++;
  31.                
  32.  
  33.             }
  34.  
  35.  

lista es la array (de string) que contiene los nombres de servidores. Como no estoy en el curro, la excepción ocurre por que es un "host desconocido". Pero lo que quiero es que aun así aparezca la form desde el principio.
pantalla es una textbox multilinea, simulando una consola (cmd).

Un saludo
« última modificación: Viernes 5 de Marzo de 2010, 16:04 por Vixente »

tannke

  • Miembro MUY activo
  • ***
  • Mensajes: 152
  • Nacionalidad: es
    • Ver Perfil
Re: PingException
« Respuesta #1 en: Viernes 5 de Marzo de 2010, 10:12 »
0
muy buenas.
No pones donde y desde donde llamas al codigo, por lo que te esta pasando, seguramente lo estes llamando desde el evento:
private void Form1_Load(object sender, EventArgs e)
{ ... }
o incluso desde el constructor:
public Form1()
        {
            InitializeComponent();
        }
A mi me paso lo mismo no hace mucho, llamaba dede el evento load, y hasta que este termina de ejecutar no me aparecia el Form.
Lo primero que hice fue poner un boton i lanzar el codigo manualmende desde el.... pero no convencia mucho.

Al final ya desesperado probando mil cosas opté por enchufarle un timer.

El timer lo programo a 250 (ponerlo como te guste mas) y puse algo asi:
Código: C#
  1. //Se lanza al abrir el form
  2.         private void Actualizar_Load(object sender, EventArgs e)
  3.         {
  4.             timer1.Start(); //enciendo el timer
  5.         }
  6.  
  7.         //botón para volver a comprovar
  8.         private void button1_Click(object sender, EventArgs e)
  9.         {
  10.             lanzar();
  11.         }
  12.  
  13.         //timer a 250ms
  14.         private void timer1_Tick(object sender, EventArgs e)
  15.         {
  16.             timer1.Stop(); //apago el timer, ya no lo quiero mas
  17.             lanzar();
  18.         }
  19.  
  20.         private void lanzar()
  21.         {
  22.             //codigo que quiero se lance
  23.         }
  24.  

No se si es muy profesional pero funciona :)

Otra cosa, al final de tu bucle foreach (dentro de el) yo pondria la linea:
Application.DoEvents();

incluso tambien lo pondria despues de pantalla.Text+="..."; sobre todo si prueba.send(...) tiene un poco de retraso

Este procesa todos los mensajes de win que tenga en cola (hace un refresco)
Te lo pongo porque muchas veces el texbox no se rellena hasta que ha acabado todo el proceso, con el DoEvents lograras que el mensaje se vaya actualizando

Espero te sirva. un saludo

eltruhanero

  • Miembro activo
  • **
  • Mensajes: 85
    • Ver Perfil
Re: PingException
« Respuesta #2 en: Viernes 5 de Marzo de 2010, 14:15 »
0
Me parece un poco forzado, si el codigo que lanzas es algo pesado y a la vez se puede ejecutar concurrentemente con el form podes lanzar un nuevo hilo.
Código: C#
  1.  
  2. Thread pThread = new Thread(new ThreadStart(lanzar));
  3. pThread.Start();
  4.  
  5.  
el unico inconveniente q introduce esto es a la hora de interactuar con el form. Tenes q hacerlo a travez de Control.Invoke.

tannke

  • Miembro MUY activo
  • ***
  • Mensajes: 152
  • Nacionalidad: es
    • Ver Perfil
Re: PingException
« Respuesta #3 en: Viernes 5 de Marzo de 2010, 15:27 »
0
Si muy buena opción eltruhanero, no habia caido en los hilos, y si como dices el codigo es un poco pesado o largo te evitas que el form esté congelado mientras se ejecuta.

Otra opción tambien podria ser el BackgroundWorker usando el evento ProgressChanged para mostrar los datos en pantalla.
"jejej(anecdota), es que una vez me pelee con el Invoke haciendo una libreria(dll) con un thread y queria que me devolviara el dato en el mismo hilo del form y sin tener que usar el invoke en el form, no hubo manera con el thread por lo que recurrí al backgrounworker y desde entonces lo utilizo (si puedo) antes que los threads"
Ejemplo con tu codigo:
Código: C#
  1. private BackgroundWorker bw = new BackgroundWorker();
  2.  
  3.         private void Form1_Load(object sender, EventArgs e)
  4.         {
  5.             bw.WorkerReportsProgress = true;
  6.             bw.DoWork += new DoWorkEventHandler(bw_DoWork);
  7.             bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
  8.             bw.RunWorkerAsync();
  9.         }
  10.  
  11.         void bw_DoWork(object sender, DoWorkEventArgs e)
  12.         {
  13.             BackgroundWorker worker = sender as BackgroundWorker;
  14.             Ping prueba = new Ping();
  15.  
  16.             foreach (string a in lista)
  17.             {
  18.                 worker.ReportProgress(0, lista[i]);
  19.                 worker.ReportProgress(0, "...");
  20.  
  21.                 try
  22.                 {
  23.                     PingReply respuesta = prueba.Send(lista[i], 100);
  24.                     if (respuesta.Status == IPStatus.Success)
  25.                     {
  26.                         worker.ReportProgress(0, "OK");
  27.                     }
  28.                     else
  29.                     {
  30.                         worker.ReportProgress(0, "error!");
  31.                     }
  32.                 }
  33.                 catch (PingException ex)
  34.                 {
  35.                     worker.ReportProgress(0, ex.InnerException.Message);
  36.                 }
  37.  
  38.                 worker.ReportProgress(0, "rn");
  39.                 i++;
  40.  
  41.  
  42.             }
  43.         }
  44.  
  45.         void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
  46.         {
  47.             string dato = e.UserState.ToString();
  48.             pantalla.Text += dato;
  49.         }  
  50.  

saludos

Vixente

  • Nuevo Miembro
  • *
  • Mensajes: 2
    • Ver Perfil
Re: PingException
« Respuesta #4 en: Viernes 5 de Marzo de 2010, 16:04 »
0
Muchas gracias a ambos, es más de lo que esperaba :)