2010-03-09 11 views
5

estoy teniendo problemas para conseguir mi interfaz gráfica de usuario a aparecer y se congela mientras se ejecuta (y esperando a) un proceso de exterior. En este caso, drivers.exe es un programa muy simple en el que el usuario simplemente hace clic en "Aceptar". Entonces cada vez que hago clic en Aceptar, sale. Estoy intentando simplemente hacer que mi número de registro de franjas de estado suba (realmente rápido) a medida que se ejecuta drivers.exe. Pero en la práctica, mi GUI nunca aparece hasta que se cierra drivers.exe.la ejecución de otro proceso sin GUI congelación

private void run_drivers() 
     { 
      Console.WriteLine("Start Driver"); 
      int driver_timeout_in_minutes = 20; 
      System.Diagnostics.Process driverproc = System.Diagnostics.Process.Start(Application.StartupPath + "\\" + "drivers.exe"); 
      driverproc.WaitForExit(driver_timeout_in_minutes * 1000 * 60); //uses milliseconds, we must convert 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      ThreadStart worker = new ThreadStart(run_drivers); 
      Console.WriteLine("Main - Creating worker thread"); 
      toolStripStatusLabel1.Text = "hi"; 
      Thread t = new Thread(worker); 
      t.IsBackground = true; 
      t.Start(); 
      Console.WriteLine("Main - Have requested the start of worker thread"); 

      int i = 0; 
      while (t.IsAlive) 
      { 
       i++; 
       toolStripStatusLabel1.Text = i.ToString(); 
      } 
      Console.WriteLine("Dead"); 
     } 

Respuesta

3

Usted debe mirar en un BackgroundWorker, como lo hace todo el trabajo para usted roscado

+0

¿Me puede mostrar cómo? Le di una oportunidad, y realmente no funcionó en absoluto. Mi forma aún no se muestra ... en absoluto, de hecho. – Adam

+2

El problema es el ciclo "while (t.IsAlive)". Necesita sacar eso de la interfaz de usuario, ya sea que use BackgroundWorker o no. – Phil

2

La razón de que su forma no aparece hasta que se ha quedado Drivers.exe se debe a que se está ejecutando desde Drivers.exe dentro de Form.Load. Form.Load se produce antes de que se muestre el formulario. Intente ejecutar drivers.exe en Form.Shown en su lugar.

Además, se while(t.IsAlive) técnicamente bloquear el hilo de interfaz de usuario. Si eso no es lo que quieres, se debe quitar del hilo principal. También es probable que desee llamar al toolStripStatusLabel1.Refresh() para forzar la actualización de la etiqueta después de configurar el texto.

+0

Ya sea que el código se ejecute en Form.Load o posterior, el subproceso de la interfaz de usuario no tendrá tiempo para pintar la pantalla cuando se ejecute como se muestra. –

0

no ponen ningún bucle en hilo de interfaz gráfica de usuario. congelará tu aplicación. Loop tiene que estar en el hilo de fondo que debe actualizar toolStripStatusLabel1 a través del método Invoke.

ver este ejemplo. no probado. tal vez incluso podría trabajar como este ...

private void run_drivers() 
    { 
     Console.WriteLine("Start Driver"); 
     int driver_timeout_in_minutes = 20; 
     System.Diagnostics.Process driverproc = System.Diagnostics.Process.Start(Application.StartupPath + "\\" + "drivers.exe"); 
     int i = 0; 
     var action = new Action<int>(x => { toolStripStatusLabel1.Text = i.ToString(); }) 
     while (!driverproc.HasExited) 
     { 
      i++; 
      toolStripStatusLabel1.Invoke(action); 
     } 

     Console.WriteLine("Dead"); 
     // start another thread here... 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     ThreadStart worker = new ThreadStart(run_drivers); 
     Console.WriteLine("Main - Creating worker thread"); 
     toolStripStatusLabel1.Text = "hi"; 
     Thread t = new Thread(worker); 
     t.IsBackground = true; 
     t.Start(); 
     Console.WriteLine("Main - Have requested the start of worker thread"); 
    } 
+0

Bien, eso tiene sentido. ¿Pero cómo debo esperar para ejecutar una función hasta que termine otra? Por ejemplo, supongamos que deseo ejecutar func_2 solo después de que se complete func_2, los cuales tardarán varios minutos en completarse. – Adam

+0

inicia un nuevo hilo en la última línea del método 'run_drivers()'. simplemente aléjate de los bucles en el hilo de GUI. –

0

Una solución podría utilizar, al tiempo que conserva su estructura de código actual, es actualizar periódicamente la interfaz de usuario en un hilo timer, parando el cronómetro cuando el hilo termina. Al hacer esto, pasará de un ciclo a un diseño basado en eventos, y le dará tiempo al hilo de la interfaz de usuario para pintar su formulario.

// create a System.Windows.Forms.Timer through the designer or in code. 
// give it a short interval if you want the counter to increment quickly. 

int counter; 

private void Form1_Load(object sender, EventArgs e) 
{ 
    ... 
    t.Start(); 
    counter = 0; 
    timer.Start(); 
    .... 
} 

private void timer_Tick(object sender, EventArgs e) 
{ 
    if (t.IsAlive) 
    { 
     counter++; 
     toolStripStatusLabel1.Text = counter.ToString(); 
    } 
    else 
    { 
     timer.Stop(); 
    } 
} 

(no probado)

Cuestiones relacionadas