2009-04-02 36 views

Respuesta

15

Se puede usar un BackgroundWorker y luego cambiar la interfaz de usuario de la siguiente manera:

control.Invoke((MethodInvoker)delegate { 
    control.Enabled = true; 
}); 
+0

Absolutamente la forma más fácil que he encontrado, y he intentado una multitud de soluciones de subprocesos de actualización de interfaz de usuario. Tengo mi voto. – GONeale

+0

Usted gana por usar la menor cantidad de texto y por mostrar el ejemplo/explicación más clara. Kudos –

+0

Gracias manera más sencilla de ahorrar mi tiempo. – Tirth

1

¿Qué hay de usar la clase BackgroundWorker de Win Form en lugar de la implementación de sincronización manual de thead?

3

Supongo que estamos hablando de WinForms aquí? Necesitará tener un solo hilo gestionando esto: el hilo que creó el control en cuestión. Si desea hacer esto desde un hilo diferente, que puede detectar usando Control.InvokeRequired, entonces debe usar el método Control.Invoke para ordenar esto en el hilo correcto. Busca esa propiedad y método (respectivamente) para algunos patrones comunes al hacer esto.

+0

También puede utilizar BeginInvoke() de manera segura en la mayoría de los casos, a menos que desee ordenar cualquier excepción lanzada de nuevo al hilo invocado. – Quibblesome

+0

'InvokeRequired/BeginInvoke' es demasiado prolijo, IMO. –

1

Use SynchronizationContext para ordenar las llamadas al subproceso de interfaz de usuario si desea modificar la interfaz de usuario mientras el subproceso que no está en la interfaz de usuario aún se está ejecutando. De lo contrario, use BackgroundWorker.

1
void button1_Click(object sender, EventArgs e) { 
    var thread = new Thread(ParalelMethod); 
    thread.Start("hello world"); 
} 
void ParalelMethod(object arg) { 
    if (this.InvokeRequired) { 
     Action<object> dlg = ParalelMethod; 
     this.Invoke(dlg, arg); 
    } 
    else { 
     this.button1.Text = arg.ToString(); 
    } 
} 
6

Si está usando C# 3.5, es muy fácil de usar métodos de extensión y lambdas para evitar la actualización de la interfaz de usuario de otros hilos

public static class FormExtensions 
{ 
    public static void InvokeEx<T>(this T @this, Action<T> action) where T : Form 
    { 
    if (@this.InvokeRequired) 
    { 
     @this.Invoke(action, @this); 
    } 
    else 
    { 
     action(@this); 
    } 
    } 
} 

Así que ahora se puede utilizar en cualquier forma InvokeEx y acceder a propiedades/campos que no son parte de Form.

this.InvokeEx(f => f.label1.Text = "Hello"); 
Cuestiones relacionadas