.net multithreading begininvoke

.net - ¿Deben todos los BeginInvoke ser seguidos por un EndInvoke?



multithreading (3)

Esta página en la documentación de MS , que cubre la asincronía en las aplicaciones de Windows Forms, establece:

Puede llamar a EndInvoke para recuperar el valor de retorno del delegado, si es necesario, pero esto no es necesario. (énfasis añadido)

Esta página que cubre el caso general de los delegados asíncronos , establece algo diferente:

Independientemente de la técnica que utilice, siempre llame a EndInvoke para completar su llamada asíncrona.

Estos dos parecen estar en conflicto directo.

¿Cual es verdad? ¿Alguien puede explicar?

Véase también, un post de Phil Haack .

Relacionado: ¿EndInvoke es opcional, algo así como opcional, definitivamente no es opcional?


A menos que la documentación de una interfaz indique explícitamente, de lo contrario, debe llamar a EndInvoke para cada lugar al que llame BeginInvoke. La razón principal es que EndInvoke es la única vez que el propietario puede liberar de manera segura ciertos recursos que pueden asignarse para la llamada BeginInvoke (como WaitHandle).

Pero hay excepciones a esta regla. Las API como Control.BeginInvoke no requieren un EndInvoke pero están explícitas en la documentación.


Ambos son ciertos, son llamadas diferentes.

En general , siempre debe llamar a EndInvoke para asegurarse de que se liberen todos los recursos adquiridos por la llamada asíncrona.

Sin embargo, el equipo de Windows Forms ha garantizado que no necesita hacer esto para Control.Invoke . Puede que necesites hacerlo para otras implementaciones de ISynchronizeInvoke .


He usado el método de "apagar y olvidar" con los delegados antes de que los resultados fueran "útiles si están disponibles, pero no son necesarios". Solo recuerda que no tienes garantías de finalización con ese método. En particular, aquí hay un lugar que lo uso:

  • Iniciar un delegado para comprobar las actualizaciones de la aplicación
  • El delegado comienza una solicitud web con un tiempo de espera
  • Si se produce un error / tiempo de espera, o si la aplicación está actualizada, el método simplemente devuelve
  • Si la aplicación está desactualizada, coloco un mensaje de systray que no roba focos y lo indica (no hay un icono de systray a menos que la actualización esté disponible)

De cualquier manera, la aplicación continúa sin interrupciones.