He leído opiniones contradictorias sobre si cada BeginInvoke() tiene que coincidir con un EndInvoke(). ¿Hay alguna fuga u otros problemas asociados con NO llamar a EndInvoke()?¿Es opcional la opción EndInvoke(), opcional o definitivamente no es opcional?
Respuesta
Delegate.EndInvoke se documenta como llamarás esta (es decir, es necesario - fugas demás suceda) - a partir msdn:
Nota Importante
No importa qué técnica use, siempre llame a EndInvoke para completar su asincrónico c todas.
Control.EndInvoke está bien ignorar para el fuego y olvida métodos - desde msdn:
Puede llamar EndInvoke para recuperar el valor retorno del delegado, si NECESARIO, pero esto no es requerido.
Sin embargo - si está utilizando Delegate.BeginInvoke
y no desea que el resultado, considere el uso de ThreadPool.QueueUserWorkItem
lugar - que va a hacer la vida mucho más fácil, y evitar el dolor de IAsyncResult
etc.
Gracias Marc, eso es lo que motivó la pregunta: estaba mirando a través de Richter y noté QueueUserWorkItem, y pensé "espera, por qué estoy usando BeginInvoke/EndInvoke en otro lugar". – endian
@endian - de hecho: la mayoría del uso de BeginInvoke se puede hacer más simplemente con ThreadPool; el BeginInvoke es quizás útil para hacer algunas cosas y reunirlas de nuevo después ... –
Enlightened. ¡Gracias! – rpattabi
EndInvoke no es opcional.
Más información here
Gracias Luca - respuesta aceptada. – endian
... para delegados, al menos ;-p –
desde su enlace: "La única excepción documentada a la regla de la que soy consciente es en Windows Forms, donde se le permite oficialmente llamar a Control.BeginInvoke sin molestarse en llama a Control.EndInvoke ". – Avram
Y llamada EndInvoke no es una llamada opcional, es una parte del contrato. Si llama a BeginInvoke, debe llamar a EndInvoke.
Ejemplo clásico de por qué es necesario. Es muy posible que IAsyncResult devuelto por BeginInvoke haya asignado recursos asociados. Más comúnmente es una especie de WaitHandle. Como IAsyncResult no implementa IDisposable, se debe elegir otro lugar para liberar los recursos. El único lugar para hacerlo es EndInvoke.
Discuto brevemente este problema en la siguiente publicación del blog.
http://blogs.msdn.com/jaredpar/archive/2008/01/07/isynchronizeinvoke-now.aspx
Gracias Jared, muy apreciado. – endian
EndInvoke no es opcional, ya que es el lugar donde se lanzan excepciones si algo ha ido mal en el procesamiento asincrónico.
De todos modos no debería haber ninguna fuga porque si el IAsyncResult está llevando a cabo algún recurso nativo que debe implementar correctamente IDisposable y disponer dichos recursos cuando el GC llama a su finalizador.
Es solo opcional si no le importa que la memoria de su programa crezca demasiado. El problema es que el GC se mantiene en todas las referencias en su hilo, porque es posible que desee llamar a EndInvoke en algún momento. Me gustaría ir con la respuesta de Marc, el grupo de temas te hará la vida más fácil. Sin embargo, debes tener cuidado si generas hilos de tus hilos, ya que está limitado en la cantidad de hilos que puede girar.
No es opcional porque llamar a BeginInvoke utiliza un WaitHandle que a su vez hace uso de un objeto kernel que mantiene un recuento de cuántas referencias se necesitan.Llamar a EndInvoke descarta con gracia el identificador que disminuye ese contador en el objeto kernel y cuando ese conteo llega a cero, el administrador de objetos del kernel lo destruirá.
Cada respuesta en esta publicación dice que EndInvoke() no es opcional. Sin embargo, encontré el siguiente comentario altamente calificado que es la respuesta aceptada en este hilo SO:
"Tenga en cuenta que el equipo de Windows Forms ha garantizado que puede usar Control.BeginInvoke de una manera 'disparar y olvidar' - es decir, sin siempre llamando a EndInvoke. Esto no ocurre con las llamadas asincrónicas en general: normalmente cada BeginXXX debe tener una llamada EndXXX correspondiente, generalmente en la devolución de llamada ".
En mi humilde opinión, es una lástima que 'Control.BeginInvoke' y' Delegate.BeginInvoke' compartan el mismo nombre, ya que tienen una semántica totalmente diferente; a decir verdad, tengo curiosidad sobre por qué los tipos de delegado definen 'BeginInvoke' como un método de instancia, en lugar de tener' Delegate.Bind (params) 'devolver un' MethodInvoker' [delegado de cero argumentos] que invocaría al delegado con los parámetros especificados, y que podrían pasarse a, por ejemplo, un método 'ThreadPool.BeginInvoke'. – supercat
+1 para esta importante distinción. El omnisciente comentario de Skeet (citado anteriormente) es muy relevante para quienes consideran situaciones Control.InvocarRequisitos. –
- 1. EndInvoke() - ¿opcional o no?
- 2. ¿Por qué la devolución 0 es opcional?
- 3. ¿La etiqueta <tr> es opcional?
- 4. ¿Es posible mover un impulso :: opcional?
- 5. Rails opcional /: ruta local
- 6. Patrón Regexp Carácter opcional
- 7. Doctrine Cartografía OneToOne opcional
- 8. parámetro de plantilla Opcional
- 9. opcional `operador new`
- 10. Ninject. Inyección opcional
- 11. PL/SQL opcional donde
- 12. problema Scala constructor opcional
- 13. RavenDB - Opcional en la cláusula
- 14. Opcional Anónimo Método
- 15. Opcional Ant arg
- 16. ¿Por qué C# se rompe si no es opcional?
- 17. ¿Cómo marcar que un argumento es opcional en PHPDoc?
- 18. ¿La palabra clave 'evento' es opcional en C#?
- 19. carga del archivo codeigniter - ¿opcional?
- 20. subparser argparse opcional (para --version)
- 21. pasar una variable booleana opcional
- 22. Opcional [Obligatorio] en tipos complejos
- 23. Importación de un módulo opcional
- 24. enrutamiento con un parámetro opcional
- 25. Primero argumento opcional en JavaScript
- 26. extraño "Argumento no opcional" error en VBA
- 27. El argumento opcional no se puede borrar?
- 28. F # Opcional registro de campo
- 29. ¿Llamar explícitamente a base() en constructores derivados es opcional?
- 30. ¿Qué significa cuando el método java.util.Iterator.remove() es 'operación opcional'?
También puede ser que desee ver: http://marcgravell.blogspot.com/2009/02/async-without-pain.html –