2011-02-09 12 views
5

Entiendo por qué los controles de GUI tienen afinidad de subprocesos.¿Por qué los controles WinForms/WPF no usan Invoke internamente?

Pero ¿por qué los controles no usan la invocación interna en sus métodos y propiedades?

Ahora usted tiene que hacer este tipo de cosas sólo para actualizar el valor TextBox:

this.Invoke(new MethodInvoker(delegate() 
{ 
    textBox.Text = "newValue"; 
} 

Mientras que utilizando sólo textBox.Text = "newValue"; sería suficiente para representar a la misma lógica.

Todo lo que tendría que hacer es cambiar textBox.Text lógica de esto (pseudocódigo):

public string Text 
{ 
    set 
    { 
     if(!this.InvokeRequired) 
      // do the change logic 
     else 
      throw new BadThreadException(); 
    } 
} 

Para esto:

public string Text 
{ 
    set 
    { 
     if(!this.InvokeRequired) 
      // do the change logic 
     else 
      this.Invoke(new MethodInvoker(delegate() 
      { 
       // do the change logic 
      } 
    } 
} 

Lo mismo ocurre con getters y métodos.

desde luego no estoy proponiendo para eliminar Invoke/BeginInvoke, sólo estoy preguntando por qué los controles no hacen cambiar el hilo necesaria a sí mismos en lugar de lanzar una excepción.

+0

Debido a que por lo general no debe tener una necesidad de actualizar los controles en un subproceso diferente de lo que se crearon sucesivamente.Hacerlo es un caso excepcional, así que tienes que saltar por los aros. No habría casi ningún beneficio al tener esto incorporado. –

+0

Supongo que cualquier "Invocación" individual implica más sobrecarga, y si tiene muchos controles que invocan automáticamente, puede incurrir en problemas de rendimiento. Al arrojar el excpetion, el sistema obliga a los desarrolladores a preocuparse por los problemas de subprocesamiento, y usa Dispatcher para hacer una sola llamada Invoke con todas las asignaciones dentro. – BertuPG

Respuesta

9

Creo que de esta forma la API impone a los desarrolladores tomar decisiones explícitas y evitar errores de programación involuntarios. Aquí hay varios problemas que podría surgir de inmediato con:

1. hilo no intencional bloqueo. Si escribe en una propiedad, el hilo de llamada tendrá que bloquearse hasta que el mensaje se procese con el hilo de la interfaz de usuario. Y si llama hilo posee un recurso que el hilo de interfaz de usuario podría querer adquirir obtendrá un callejón sin salida, que es difícil de depurar (subproceso de la llamada tiene un recurso, y esperar hasta que el mensaje es procesado por el hilo de interfaz de usuario; hilo espera de interfaz de usuario hasta que se libere el recurso)

2. Sorpresas inesperadas. Si hiciéramos las operaciones de escritura implícitamente asíncronas, nos topamos con una situación en la que el lector nunca debería esperar que los valores estén siempre actualizados.

3. Repercusión en el rendimiento. Si escribe un algoritmo intensivo que utiliza el despacho de UI implícitamente, terminará con un rendimiento realmente bajo y podrá echar la culpa a los desarrolladores de frameworks. Después de todo, escribiste la ordenación que debería ejecutarse en O (n), pero por alguna razón lleva años completarla.

+1

Estaba pensando que estas podrían ser las razones también, pero ya hay tantos problemas en los hilos, así que no creo que esto suponga una gran diferencia. –

2

Bueno, a menos que alguno de los desarrolladores o implementadores del marco responda, esto solo se puede especular, pero el más obvio aunque eso surja para (al menos mi) mente es complejidad. Agregar la lógica de conmutación de hilos en todos los lugares relevantes de todos los controles llevaría a un gran aumento en su complejidad (imagine todas las pruebas necesarias para verificar el comportamiento en todas partes). Probablemente no valga la pena el esfuerzo, de modo que el trabajo se transfiere a los usuarios de los controles (nosotros, eso), que necesitan realizar este pequeño recorrido adicional en los casos en que se necesita.

+0

Supongo que sería marcar los métodos y las propiedades con un atributo y luego agregar el modificador de subprocesos en tiempo de compilación (o después - similar a lo que NotifyPropertyWeaver hace) –

+0

@mzabsky: buen punto. Eso sería más fácil, pero movería la complejidad al compilador, lo que aún sería un cambio bastante costoso. –

Cuestiones relacionadas