Subprocesos en formularios Windows Forms

He estado escribiendo aplicaciones web ASP.NET durante años, pero realmente no he trabajado en proyectos de formularios de ventanas grandes. Ahora necesito trabajar en uno, así que estoy buscando algunos consejos sobre cómo debería estructurarse idealmente un proyecto de formularios de ventanas grandes. Más específicamente, me gustaría saber cómo manejar múltiples subprocesos. Suponga que tiene un proceso que tarda un tiempo en completarse: no desea que la ventana de la interfaz de usuario se congele y no responda. Entonces esa lógica necesita moverse en un hilo separado. Si este subproceso accede a la interfaz de usuario, provocará excepciones. Invoke parece hacer el truco, ¡pero se ve muy feo y engorroso para escribir y leer!

Entonces, en realidad, ¿cuáles son las mejores prácticas? ¿Qué tipo de subprocesos se deben iniciar y cómo se deben dividir estos subprocesos entre la interfaz de usuario y la lógica? ¿Algún código de muestra para empezar?

preguntado el 12 de junio de 12 a las 08:06

Eche un vistazo a la clase BackgroundWorker, si usar Invoke le parece confuso. -

3 Respuestas

aquí hay una forma corta de usar el trabajador de fondo

        public Form1()
    {
        InitializeComponent();

        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true; //set to true to fire the progress-changed event
        worker.DoWork += doWork;
        worker.ProgressChanged += progressChanged;
    }

    void progressChanged(object sender, ProgressChangedEventArgs e)
    {
        int progress = e.ProgressPercentage; //Progress-Value
        object userState = e.UserState; //can be used to pass values to the progress-changed-event
    }

    void doWork(object sender, DoWorkEventArgs e)
    {
        object argument = e.Argument; //Parameters for the call
        bool cancel = e.Cancel; //Boolean-Value for cancel work
        object result = e.Result; //Object for a return-value
    }

Respondido el 12 de junio de 12 a las 08:06

Y hay un evento llamado RunWorkerCompleted que se activa cuando el trabajador finaliza. - Tomtom

Tan pronto como use un hilo diferente, tendrá que volver al hilo de la interfaz de usuario cuando toque la interfaz de usuario.

algunaForma.BeginInvoke() puede hacer esto, pero hay más opciones.

El BackgroundWorker puede hacer el cambio por usted.

En .NET 4.5/ C# 5 puede usar async / await; la continuación se llamará en el hilo original.

En general, trate de desenredar la lógica tanto como pueda de la interfaz de usuario para que no tenga que cambiar de hilo con demasiada frecuencia.

Respondido el 12 de junio de 12 a las 08:06

Hay muchas formas de lograr la capacidad de respuesta de la interfaz de usuario, ejecutar tareas de ejecución prolongada y lograr el paralelismo. Debe seleccionar la forma correcta para su aplicación:

Este artículo por Jon Skeet es siempre una ventaja para empezar.

  1. Puede llamar a métodos síncronos de forma asíncrona usando cualquiera de estos estilos según el diseño y los requisitos de su aplicación

  2. Más situaciones difíciles, como coordinar el trabajo de múltiples subprocesos o manejar subprocesos que bloquean

  3. Hay varias formas de exponer características asincrónicas al código del cliente. Lea aquí para el patrón asíncrono basado en eventos, que prescribe la forma recomendada para que las clases presenten un comportamiento asíncrono.

  4. Trabajador de fondo resulta útil cuando tiene una sola tarea de ejecución prolongada.

Espero que esto te dé una ventaja.

Respondido el 12 de junio de 12 a las 09:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.