update thread hilos from form example ejemplo control c# user-interface event-handling invoke invokerequired

c# - hilos - invokerequired thread



¿Qué hay de malo en llamar a Invoke, independientemente de InvokeRequired? (6)

He visto la configuración común para el acceso cruzado a un control GUI, como se discute aquí: La forma más corta de escribir un método de acceso seguro para subprocesos a un control de formularios de Windows

Todos los hits web que encontré describen algo similar.

Sin embargo, ¿por qué necesitamos verificar InvokeRequired? ¿No podemos simplemente llamar a Invoke directamente?

Supongo que la respuesta es no, entonces mi verdadera pregunta es ''¿por qué?


El problema es que los controles de la GUI requieren que solo el código que se ejecuta en el mismo subproceso que se usó para crear una instancia del control de la GUI pueda acceder al control de la GUI. Las razones detrás de este requisito están relacionadas con la forma en que se diseñó Windows. Baste decir que sería muy difícil cambiar esto.

InvokeRequired comprueba la identidad del subproceso que se ejecuta actualmente con la identidad del subproceso de creación de instancias. Si son iguales, el código puede interactuar libremente con el control. De lo contrario, el código debe ordenar los datos desde el hilo actual al hilo de creación de instancias. Este es un proceso lento y costoso y debe evitarse si es posible. Tu código funcionará si siempre invocas y es posible que no notes el impacto en el rendimiento, pero este escenario va a ser cada vez más común a medida que entren en funcionamiento los sistemas multi-core. Lo mejor es no crear "nudos" de código que se tengan que deshacer más adelante.


La Invocación llamará el código a través de Delegado y no directamente, lo que sería costoso.

Es rentable llamar a Invoke solo cuando lo requiera. Por lo tanto, InvokeRequired se utiliza para averiguar si la llamada se realiza desde el mismo subproceso u otro subproceso.


Si intenta invocar antes de que se cree un identificador de ventana (por ejemplo, al llamar al constructor del formulario), obtendrá una InvalidOperationException . Por lo tanto, generalmente se InvokeRequired control InvokeRequired .

Ver MSDN para más detalles.


Una razón por la que puedo pensar es en el rendimiento. Si la mayoría de las veces el hilo de llamada es el mismo que el del hilo de creación, entonces tendrá una sobrecarga inesperada.


InvokeRequired básicamente le dice si está ejecutando en el hilo correcto o no. Si no está en el hilo correcto, necesita ordenar la tarea en el hilo correcto, de lo contrario no lo haría. De ahí la necesidad del cheque.


Desde hilos que no son UI, no podemos tocar la interfaz de usuario: pueden pasar cosas muy malas, ya que los controles tienen afinidad por el hilo. Por lo tanto, a partir de un hilo que no sea UI, debemos (por lo menos) llamar a Invoke o BeginInvoke .

Sin embargo, para hilos de UI, no queremos llamar a Invoke mucho tiempo; el problema es que si ya está en el hilo de la interfaz de usuario, todavía tiene la sobrecarga innecesaria de enviar un mensaje a la bomba del formulario y procesarlo.

En realidad, en la mayoría de los códigos de subprocesamiento, usted sabe que espera que se invoque un método específico en un subproceso no UI, por lo que en esos casos, no hay gastos generales adicionales: simplemente llame a Invoke .