válida través thread subprocesos operación net metodo hilos form false example delegados control checkforillegalcrossthreadcalls winforms multithreading asynchronous

winforms - thread - operación no válida a través de subprocesos backgroundworker



Actualizando la interfaz de usuario desde un hilo diferente (4)

Puede tener el efecto deseado utilizando un segundo hilo y una cola segura para hilos.

Puede crear un segundo hilo que escuche los eventos. Cuando ocurre un nuevo evento, empuja la información del evento a una cola (thread safe-synchronized).

Usando un temporizador (Windows.Forms.Timer) que verificará esa cola cada x vez y en caso de que existan nuevos eventos puede actualizar la UI.

Debido a que el temporizador se ejecuta en el hilo principal, puede actualizar la interfaz de usuario de forma segura y, si lo haces liviano, no lo bloqueará el tiempo suficiente para que se note.

Sé que esta pregunta ya se hizo antes, pero siento que no se me preguntó correctamente.

Tengo una operación intensiva y me gustaría que la interfaz de usuario siga siendo receptiva. He leído algunas publicaciones que dicen que el trabajador en segundo plano es el mejor camino a seguir, sin embargo, creo que esto supone que tienes el código fuente para la tarea intensiva.

Tengo una biblioteca para la que no tengo un código fuente, la única forma en que puedo verificar el progreso es adjuntarme a eventos que son despedidos y obtener información de esa manera.

El ejemplo que vi en el sitio de MSDN asumió que uno tendría la fuente.

Sé cómo obtener progreso (que es un valor porcentual) adjuntándome a eventos, pero ¿cómo recupero ese valor en la IU?


La siguiente respuesta se basa en mi presentimiento y en realidad no lo he hecho una prueba con libs de terceros.

  • Llame al código de lib de terceros, como de costumbre, llama en un hilo de fondo simple (no BackGroundWorker).
  • Adjunte los eventos de los componentes de la biblioteca a los controladores de eventos normales en su código (destinados a actualizar la interfaz de usuario).
  • En el caso de que el código del manejador se vea así:

    private void EventHandler(object sender, DirtyEventArgs e) { if (myControl.InvokeRequired) myControl.Invoke(new MethodInvoker(MethodToUpdateUI), e); else MethodToUpdateUI(e); } private void MethodToUpdateUI(object obj) { // Update UI }



Una discusión similar es sobre esta Q. Si no puede o no quiere usar BackgroundWorker por alguna razón, puede usar su propio hilo y ordenar los eventos de nuevo en su subproceso de interfaz de usuario.

private void Initialise() { MyLibClass myLibClass = new MyLibClass(); myLibClass.SomeEvent += SomeEventHandler; ThreadPool.QueueUserWorkItem(myLibClass.StartLongTask); } private void SomeEventHandler(EventArgs e) { if (this.Dispatcher.Thread != Thread.CurrentThread) { this.Dispatcher.Invoke(delegate { DoStuffOnUIThread(e); }); } else { DoStuffOnUIThread(e); } }