En la programación de computadoras multiproceso , la invocación de método asincrónico ( AMI ), también conocida como llamadas de método asincrónico o patrón asincrónico, es un patrón de diseño en el que el sitio de la llamada no se bloquea mientras se espera que finalice el código llamado. En cambio, se notifica al hilo que llama cuando llega la respuesta. Sondear para obtener una respuesta es una opción no deseada.
Fondo
AMI es un patrón de diseño para la invocación asincrónica de métodos potencialmente de larga ejecución de un objeto . [1] Es equivalente al patrón IOU ("Te debo") descrito en 1996 por Allan Vermeulen. [2] [3]
En la mayoría de los lenguajes de programación, un método llamado se ejecuta sincrónicamente, es decir, en el hilo de ejecución desde el que se invoca. Si el método tarda mucho en completarse, por ejemplo, porque está cargando datos a través de Internet, el hilo de llamada se bloquea hasta que el método haya finalizado. Cuando esto no se desea, es posible iniciar un "hilo de trabajo" e invocar el método desde allí. En la mayoría de los entornos de programación, esto requiere muchas líneas de código, especialmente si se tiene cuidado de evitar la sobrecarga que puede causar la creación de muchos subprocesos. AMI resuelve este problema porque aumenta un método de objeto potencialmente de larga duración ("síncrono") con una variante "asincrónica" que regresa inmediatamente, junto con métodos adicionales que facilitan la recepción de notificaciones de finalización o la espera de finalización en un tiempo posterior.
Un uso común de AMI es el patrón de diseño de objetos activos . Las alternativas son la invocación de métodos síncronos y los objetos futuros . [4] Un ejemplo de una aplicación que puede hacer uso de AMI es un navegador web que necesita mostrar una página web incluso antes de que se carguen todas las imágenes.
Dado que el método es un caso especial de procedimiento , la invocación de método asíncrono es un caso especial de llamada a procedimiento asíncrono .
Implementaciones
Clase Java
La clase FutureTask [5] en Java usa eventos para resolver el mismo problema. Este patrón es una variante de AMI cuya implementación conlleva más gastos generales, pero es útil para objetos que representan componentes de software .
.NET Framework
- Patrón de modelo de programación asincrónica (APM) (utilizado antes de .NET Framework 2.0) [6]
- Patrón asincrónico basado en eventos (EAP) (utilizado en .NET Framework 2.0) [7]
- Patrón asincrónico basado en tareas (TAP) (utilizado en .NET Framework 4.0) [8]
Ejemplo
El siguiente ejemplo se basa libremente en un estilo AMI estándar utilizado en .NET Framework . [9] Dado un método Accomplish
, se agregan dos métodos nuevos BeginAccomplish
y EndAccomplish
:
clase Ejemplo { Resultados lograr ( args ... ) IAsyncResult BeginAccomplish ( args ... ) Resultado EndAccomplish ( IAsyncResult una ) ... }
Al llamar BeginAccomplish
, el cliente recibe inmediatamente un objeto de tipo AsyncResult
(que implementa la IAsyncResult
interfaz), por lo que puede continuar el hilo de llamada con trabajo no relacionado. En el caso más simple, eventualmente no hay más trabajo de este tipo, y el cliente llama EndAccomplish
(pasando el objeto recibido previamente), que se bloquea hasta que el método se completa y el resultado está disponible. [10] El AsyncResult
objeto normalmente proporciona al menos un método que permite al cliente consultar si el método de larga duración ya se ha completado:
interfaz IAsyncResult { bool HasCompleted () … }
También se puede pasar un método de devolución de llamada a BeginAccomplish
, para que se invoque cuando se complete el método de ejecución prolongada. Suele llamar EndAccomplish
para obtener el valor de retorno del método de larga duración. Un problema con el mecanismo de devolución de llamada es que la función de devolución de llamada se ejecuta naturalmente en el hilo de trabajo (en lugar de en el hilo de llamada original), lo que puede provocar condiciones de carrera. [11] [12]
En la documentación de .NET Framework, el término patrón asincrónico basado en eventos se refiere a un estilo de API alternativo (disponible desde .NET 2.0) utilizando un método denominado en AccomplishAsync
lugar de BeginAccomplish
. [13] [14] Una diferencia superficial es que en este estilo el valor de retorno del método de larga duración se pasa directamente al método de devolución de llamada. Mucho más importante, la API utiliza un mecanismo especial para ejecutar el método de devolución de llamada (que reside en un objeto de evento de tipo AccomplishCompleted
) en el mismo hilo en el que BeginAccomplish
se llamó. Esto elimina el peligro de las condiciones de carrera, lo que hace que la API sea más fácil de usar y adecuada para los componentes de software; por otro lado, esta implementación del patrón viene con una sobrecarga adicional de creación y sincronización de objetos. [15]
Referencias
- ^ "Invocación de método asincrónico" . Programación distribuida con hielo . ZeroC, Inc. Archivado desde el original el 5 de enero de 2008 . Consultado el 22 de noviembre de 2008 .
- ^ Vermeulen, Allan (junio de 1996). "Un patrón de diseño asincrónico" . Diario del Dr. Dobb . Consultado el 22 de noviembre de 2008 .
- ^ Nash, Trey (2007). "Subprocesamiento en C #". C # acelerado 2008 . Presione. ISBN 978-1-59059-873-3.
- ^ Lavanda, R. Greg; Douglas C. Schmidt . "Objeto activo" (PDF) . Archivado desde el original (PDF) el 24 de septiembre de 2012 . Consultado el 22 de noviembre de 2008 . Cite journal requiere
|journal=
( ayuda ) - ^ "Clase FutureTask" . Oráculo. 2011. Archivado desde el original el 25 de junio de 2013 . Consultado el 29 de junio de 2015 .
- ^ "Modelo de programación asincrónica" . Microsoft. 2015 . Consultado el 29 de junio de 2015 .
- ^ "Resumen de patrones asincrónicos basados en eventos" . Microsoft. 2015 . Consultado el 29 de junio de 2015 .
- ^ "Patrón asincrónico basado en tareas" . Microsoft. 2015 . Consultado el 29 de junio de 2015 .
- ^ "Patrones de diseño de programación asincrónica" . .NET Framework Developer's Guide . Red de desarrolladores de Microsoft. Archivado desde el original el 22 de noviembre de 2008 . Consultado el 22 de noviembre de 2008 .
- ^ "Descripción general de la programación asincrónica" . .NET Framework Developer's Guide . Red de desarrolladores de Microsoft. Archivado desde el original el 7 de diciembre de 2008 . Consultado el 22 de noviembre de 2008 .
- ^ "Uso de un delegado AsyncCallback para finalizar una operación asincrónica" . .NET Framework Developer's Guide . Red de desarrolladores de Microsoft. Archivado desde el original el 23 de diciembre de 2008 . Consultado el 22 de noviembre de 2008 .
- ^ "Problemas de concurrencia" . Programación distribuida con hielo . ZeroC, Inc. Archivado desde el original el 28 de marzo de 2008 . Consultado el 22 de noviembre de 2008 .
- ^ Christian Nagel; Bill Evjen; Jay Glynn; Karli Watson y Morgan Skinner (2008). "Patrón asincrónico basado en eventos". Profesional C # 2008 . Wiley. págs. 570 –571. ISBN 9780470191378.
- ^ "Programación multiproceso con el patrón asincrónico basado en eventos" . .NET Framework Developer's Guide . Red de desarrolladores de Microsoft. Archivado desde el original el 25 de diciembre de 2008 . Consultado el 22 de noviembre de 2008 .
- ^ "Decidir cuándo implementar el patrón asincrónico basado en eventos" . .NET Framework Developer's Guide . Red de desarrolladores de Microsoft. Archivado desde el original el 22 de noviembre de 2008 . Consultado el 22 de noviembre de 2008 .
Otras lecturas
- Chris Sells e Ian Griffiths (2007). "Apéndice C.3: El patrón asíncrono basado en eventos". Programación de WPF . O'Reilly. págs. 747 –749. ISBN 9780596510374.
- Usar llamadas a métodos asincrónicos en C #