La interfaz de usuario de la aplicación WinForm se bloquea durante la operación de larga ejecución

Tengo una aplicación de formularios de Windows en la que necesito usar un bucle for que tiene una gran cantidad de llamadas remotas alrededor de 2000 – 3000 llamadas,

y mientras ejecuto el ciclo for, pierdo mi control sobre los controles de formulario y formulario, ya que se convierte en un proceso grande y en algún momento muestra “No responde”, pero si espero durante un tiempo, vuelve a aparecer, creo que necesito usarlo. algún modelo de subprocesamiento para eso, ¿hay alguna idea, cómo puedo proceder para resolver el problema?

Necesita realizar la operación de larga ejecución en una cadena de fondo.

Hay varias maneras de hacer esto.

  1. Puede poner en cola la llamada al método de ejecución en un subproceso de agrupación de subprocesos (consulte aquí ):

     ThreadPool.QueueUserWorkItem(new WaitCallback(YourMethod)); 

    En .NET 4.0 puedes usar TaskFactory :

     Task.Factory.StartNew(() => YourMethod()); 

    Y en .NET 4.5 y posterior, puede (y debería, en lugar de TaskFactory.StartNew() ) usar Task.Run() :

     Task.Run(() => YourMethod()); 
  2. Puede usar un BackgroundWorker para tener más control sobre el método si necesita cosas como actualizaciones de progreso o notificación cuando finalice. Arrastre el control a BackgroundWorker en su formulario y adjunte su método al evento dowork. Luego, simplemente inicie al trabajador cuando desee ejecutar su método. Por supuesto, puede crear el BackgroundWorker manualmente desde el código, solo recuerde que debe deshacerse de él cuando haya terminado.

  3. Crea un hilo totalmente nuevo para que tu trabajo suceda. Este es el más complejo y no es necesario a menos que necesite un control realmente detallado sobre el hilo. Consulte la página MSDN en la clase Thread si desea obtener más información al respecto.

Recuerde que con algo enhebrado, no puede actualizar la GUI ni cambiar los controles de GUI de una cadena de fondo. Si desea hacer algo en la GUI, debe usar Invoke (y InvokeRequired) para volver a activar el método en la secuencia de la GUI. Mira aquí .

  private voidForm_Load(object sender, EventArgs e) { MethodInvoker mk = delegate { //your job }; mk.BeginInvoke(callbackfunction, null); } private void callbackfunction(IAsyncResult res) { // it will be called when your job finishes. } 

use MethodInvoker es la forma más fácil.

No se necesita hilo. Use Application.DoEvents(); //repaint or respond to msg Application.DoEvents(); //repaint or respond to msg Por ejemplo:

 foreach (DirectoryInfo subDir in dirInfo.EnumerateDirectories()) { count = count + 1; listBoxControl4.Items.Add(count.ToString() + ":" + subDir.FullName); Application.DoEvents(); //allow repaint to see status ProduceListing(subDir, " "); } 

Esto irá a todas las carpetas recursivamente y escribirá los nombres en un cuadro de lista. Esto puede llevar mucho tiempo. Con DoEvents (), mostrará el progreso en cada ciclo. Básicamente, la llamada permite que Windows en este hilo actualice cualquier cosa en el bucle de msg de Windows. Asegúrese de ver la recursión involuntaria, ya que cualquier control en el formulario se volverá a hacer clic aunque el primero no se haya completado. Esto funciona bien (Es una copia de la antigua llamada Delphi Application.ProcessMessages (). Puede buscar eso para ver por qué funciona y qué buscar.

Obviamente, necesita usar hilos de fondo. Te sugiero que leas este e-book gratuito .