En la programación informática 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 realiza la llamada cuando llega la respuesta. El sondeo para obtener una respuesta es una opción no deseada.
AMI es un patrón de diseño para la invocación asincrónica de métodos potencialmente de larga duració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 de forma sincrónica, es decir, en el hilo de ejecución desde el que se invoca. Si el método tarda mucho tiempo en completarse, por ejemplo, porque está cargando datos a través de Internet, el hilo que lo invoca se bloquea hasta que el método haya terminado. 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 hilos. AMI resuelve este problema al ampliar un método de objeto potencialmente de larga ejecución ("sincrónico") 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 momento posterior.
Un uso común de AMI es en el patrón de diseño de objetos activos . Las alternativas son la invocación de métodos sincrónicos 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 asincrónico es un caso especial de llamada a procedimiento asincrónico .
La clase FutureTask [5] en Java utiliza eventos para resolver el mismo problema. Este patrón es una variante de AMI cuya implementación conlleva más sobrecarga, pero es útil para objetos que representan componentes de software .
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 { Resultado Cumplir ( args … ) IAsyncResult BeginAccomplish ( args … ) Resultado FinAccomplish ( IAsyncResult a ) … }
Al llamar a 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, finalmente ya no hay más trabajo de ese tipo y el cliente llama EndAccomplish
(pasando el objeto recibido anteriormente), que se bloquea hasta que el método se haya completado 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 ejecució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 larga duración. Normalmente, se llama 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) que utiliza un método llamado AccomplishAsync
en lugar de BeginAccomplish
. [13] [14]
Una diferencia superficial es que en este estilo el valor de retorno del método de larga ejecució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 condiciones de carrera, lo que hace que la API sea más fácil de usar y adecuada para 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]
{{cite journal}}
: Requiere citar revista |journal=
( ayuda )