Modelo de programación asincrónica (APM)
Una operación asincrónica que usa el modelo de diseño IAsyncResult se implementa como dos métodos con nombre BeginOperationName
y EndOperationName
que comienzan y terminan la operación asincrónica OperationName respectivamente. Por ejemplo, la clase FileStream ofrece los métodos BeginRead y EndRead para leer bytes de un archivo de manera asincrónica. Estos métodos implementan la versión asincrónica del método Read .
Nota:
A partir de .NET Framework 4, la biblioteca TPL (Task Parallel Library, biblioteca de procesamiento paralelo basado en tareas) ofrece un nuevo modelo para programación asincrónica y paralela. Para obtener más información, vea Biblioteca TPL y Modelo asincrónico basado en tareas (TAP).
Después de llamar a BeginOperationName
, una aplicación puede seguir ejecutando instrucciones en el subproceso de llamada mientras la operación asincrónica tiene lugar en un subproceso diferente. Para cada llamada a BeginOperationName
, la aplicación debe llamar a EndOperationName
para obtener los resultados de la operación.
Comenzar una operación asincrónica
El método BeginOperationName
comienza la operación asincrónica OperationName y devuelve un objeto que implementa la interfaz IAsyncResult. Los objetosIAsyncResult almacenan información sobre una operación asincrónica. En la tabla siguiente se muestra información sobre una operación asincrónica.
Miembro | Descripción |
---|---|
AsyncState | Objeto opcional específico de la aplicación que contiene información sobre la operación asincrónica. |
AsyncWaitHandle | Un WaitHandle que se puede usar para bloquear la ejecución de la aplicación hasta que se complete la operación asincrónica. |
CompletedSynchronously | Un valor que indica si la operación asincrónica se completó en el subproceso usado para llamar a BeginOperationName en lugar de completarse en otro subproceso ThreadPool. |
IsCompleted | Un valor que indica si se ha completado la operación asincrónica. |
Un método BeginOperationName
toma los parámetros declarados en la firma de la versión sincrónica del método que se pasan por valor o por referencia. Los parámetros out no forman parte de la firma del método BeginOperationName
. La firma del método BeginOperationName
también incluye dos parámetros adicionales. El primero de estos define un delegado AsyncCallback que hace referencia a un método al que se llama cuando se completa la operación asincrónica. El llamador puede especificar null
(Nothing
en Visual Basic) si no quiere un método invocado cuando finalice la operación. El segundo parámetro adicional es un objeto definido por el usuario. Este objeto se puede usar para pasar información de estado específica de la aplicación al método invocado cuando finaliza la operación asincrónica. Si un método BeginOperationName
toma parámetros específicos de operación adicionales, como una matriz de bytes para almacenar los bytes leídos de un archivo, el delegado AsyncCallback y el objeto de estado de la aplicación son los últimos parámetros de la firma del método BeginOperationName
.
BeginOperationName
devuelve el control inmediatamente al subproceso de llamada. Si el método BeginOperationName
genera excepciones, las excepciones se generan antes de iniciarse la operación asincrónica. Si el método BeginOperationName
genera excepciones, no se invoca el método de devolución de llamada.
Finalizar una operación asincrónica
El método EndOperationName
finaliza la operación asincrónica OperationName. El valor devuelto del método EndOperationName
es del mismo tipo devuelto por su homólogo sincrónico y es específico de la operación asincrónica. Por ejemplo, el método EndRead devuelve el número de bytes leídos de un FileStream y el método EndGetHostByName devuelve un objeto IPHostEntry que contiene información sobre un equipo host. El método EndOperationName
toma los parámetros out o ref declarados en la firma de la versión sincrónica del método. Además de los parámetros del método sincrónico, el método EndOperationName
también incluye un parámetro IAsyncResult. Los autores de la llamada deben pasar la instancia devuelta por la llamada correspondiente a BeginOperationName
.
Si la operación asincrónica representada por el objeto IAsyncResult no ha finalizado cuando se llama a EndOperationName
, EndOperationName
bloquea el subproceso de llamada hasta que finaliza la operación asincrónica. Las excepciones generadas por la operación asincrónica se generan desde el método EndOperationName
. El efecto de llamar al método EndOperationName
varias veces con el mismo IAsyncResult no está definido. Del mismo modo, tampoco se ha definido la llamada al método EndOperationName
con una interfaz IAsyncResult no devuelta por el método Begin relacionado.
Nota:
En cualquiera de los escenarios sin definir, los implementadores deben considerar generar InvalidOperationException.
Nota:
Los implementadores de este patrón de diseño deben notificar al llamador que ha completado la operación asincrónica estableciendo IsCompleted en true, llamando al método de devolución de llamada asincrónica (si se especificó) y señalizando el AsyncWaitHandle.
Los desarrolladores de aplicaciones tienen varias opciones de diseño para tener acceso a los resultados de la operación asincrónica. La opción correcta depende de si la aplicación tiene instrucciones que se pueden ejecutar mientras se completa la operación. Si una aplicación no puede realizar ningún trabajo adicional hasta que recibe los resultados de la operación asincrónica, debe bloquearse la aplicación hasta que los resultados estén disponibles. Para bloquear hasta que finalice una operación asincrónica, puede usar uno de los siguientes enfoques:
Llame a
EndOperationName
desde el subproceso principal de la aplicación, bloqueando la ejecución de la aplicación hasta que finalice la operación. Para ver un ejemplo que ilustre esta técnica, consulte Bloquear la ejecución de una aplicación al finalizar una operación asincrónica.Use el AsyncWaitHandle para bloquear la ejecución de aplicaciones hasta que se completen una o más operaciones. Para ver un ejemplo que ilustre esta técnica, consulte Bloquear la ejecución de una aplicación mediante AsyncWaitHandle.
Las aplicaciones que no necesiten bloquear mientras se completa la operación asincrónica pueden usar uno de los siguientes métodos:
Sondee el estado de finalización de la operación activando la propiedad IsCompleted periódicamente y llamando a
EndOperationName
cuando finalice la operación. Para ver un ejemplo que ilustre esta técnica, consulte Sondear el estado de una operación asincrónica.Use un delegado AsyncCallback para especificar un método que se debe invocar cuando finalice la operación. Para ver un ejemplo que ilustre esta técnica, consulte Utilizar un delegado AsyncCallback para finalizar una operación asincrónica.