Hubo mucha discusión sobre esto y todos tienden a estar de acuerdo en que siempre debe llamar a Delegate.EndInvoke para evitar una pérdida de memoria (¡incluso Jon Skeet lo dijo!).No llamar a Delegate.EndInvoke puede causar pérdida de memoria ... ¿un mito?
Siempre seguí esta guía sin cuestionamientos, pero recientemente implementé mi propia clase AsyncResult y vi que el único recurso que podría tener fugas es AsyncWaitHandle.
(De hecho, no se filtra realmente porque el recurso nativo utilizado por el WaitHandle está encapsulado en un SafeHandle que tiene un Finalizer, sin embargo, agregará presión a la cola de finalización del recolector de elementos no utilizados). implementación de AsyncResult sólo inicializar el AsyncWaitHandle en la demanda ...)
la mejor manera de saber si hay una fuga es sólo para probarlo:
Action a = delegate { };
while (true)
a.BeginInvoke(null, null);
me corrieron esto por un tiempo y la memoria mantenerse entre 9-20 MB.
Vamos a comparar con Delegate.EndInvoke cuando se llama:
Action a = delegate { };
while (true)
a.BeginInvoke(ar => a.EndInvoke(ar), null);
Con esta prueba, el juego de memoria entre 9-30 MG, raro eh? (Probablemente porque tarda un poco más en ejecutarse cuando hay un AsyncCallback, por lo que habrá más delegados en cola en el ThreadPool)
¿Qué piensas ... "Myth busted"?
P.S. ThreadPool.QueueUserWorkItem es cien veces más eficiente que Delegate.BeginInvoke, es mejor usarlo para disparar & olvidar llamadas.
¡Buena pregunta! +1. Por cierto, ves demasiados MythBusters;) – RCIX
Acepto, ThreadPool.QueueUserWorkItem es un método brillante y poco utilizado. – Anton