Programación asincrónica con Async y Await (C# y Visual Basic)
Este tema contiene las secciones siguientes.
- Async mejora capacidad
- Métodos Easier Async a escribir
- Lo que sucede en un método Async
- Métodos de la API Async
- Subprocesos
- Async y Await
- Tipos de retorno y parámetros
- Convención de nomenclatura
- Temas relacionados
- Ejemplo completo
- Temas relacionados
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Three things to note in the signature: // - The method has an async modifier. // - The return type is Task or Task<T>. (See "Return Types" section.) // Here, it is Task<int> because the return statement returns an integer. // - The method name ends in "Async." async Task<int> AccessTheWebAsync() { // You need to add a reference to System.Net.Http to declare client. HttpClient client = new HttpClient(); // GetStringAsync returns a Task<string>. That means that when you await the // task you'll get a string (urlContents). Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com"); // You can do work here that doesn't rely on the string from GetStringAsync. DoIndependentWork(); // The await operator suspends AccessTheWebAsync. // - AccessTheWebAsync can't continue until getStringTask is complete. // - Meanwhile, control returns to the caller of AccessTheWebAsync. // - Control resumes here when getStringTask is complete. // - The await operator then retrieves the string result from getStringTask. string urlContents = await getStringTask; // The return statement specifies an integer result. // Any methods that are awaiting AccessTheWebAsync retrieve the length value. return urlContents.Length; }
La firma del método incluye un modificador de Async o de async. El nombre de un método async, por convención, finaliza con un sufijo “Async”. El tipo de valor devuelto es uno de los tipos siguientes: Task<TResult> si el método tiene una instrucción return en la que el operando tiene el tipo TResult. Task si el método no tiene ninguna instrucción return ni tiene una instrucción return sin operando. Void ( Sub en Visual Basic) si está escribiendo un controlador de eventos async.
Para obtener más información, vea “tipos de valor devuelto y los parámetros” más adelante en este tema. El método normalmente incluye al menos uno espera la expresión, que marca un punto en el que el método no puede continuar hasta que se completa la operación asincrónica aguardada. Mientras tanto, se suspende el método, y el control vuelve al llamador del método. La sección siguiente de este tema muestra lo que sucede en el punto de suspensión.
-
Un controlador de eventos llama a y espera el método async de AccessTheWebAsync. -
AccessTheWebAsync crea una instancia de HttpClient y llama al método asincrónico de GetStringAsync para descargar el contenido de un sitio Web como una cadena. -
Sucede algo en GetStringAsync que suspende el progreso. Quizás debe esperar un sitio Web para descargar o alguna otra actividad de bloqueo. Para evitar que los recursos, GetStringAsync hace que el control al llamador, AccessTheWebAsync. GetStringAsync devuelve Task<TResult> donde es una cadena TResult, y las asignaciones de AccessTheWebAsync la tarea a la variable de getStringTask. La tarea representa el proceso actual para la llamada a GetStringAsync, con el compromiso de generar un valor de cadena real cuando se completa el trabajo. -
Dado que getStringTask no se ha aguardado todavía, AccessTheWebAsync puede continuar con otro trabajo que no depende del resultado final de GetStringAsync. Ese trabajo se representa mediante una llamada al método sincrónico DoIndependentWork. -
DoIndependentWork es un método sincrónico que hace el trabajo y vuelve al llamador. -
AccessTheWebAsync ha ejecutado sin trabajo que puede realizar sin un resultado de getStringTask. AccessTheWebAsync después desea calcular y devolver la longitud de la cadena descargado, pero el método no puede calcular ese valor hasta que el método tiene la cadena. Por consiguiente, AccessTheWebAsync utiliza un operador de aguardar para suspender el progreso y producir el control al método que llamó AccessTheWebAsync. AccessTheWebAsync devuelve Task(Of Integer) o Task<int> al llamador. La tarea representa una sugerencia de generar un resultado entero que es la longitud de la cadena descargado.
Nota
Si se completa GetStringAsync (y por consiguiente getStringTask) antes de que AccessTheWebAsync lo espera, permanece el control en AccessTheWebAsync. El costo de suspensión y después de volver a AccessTheWebAsync se perderán si el proceso denominado asincrónico (getStringTask) ya se ha completado y AccessTheWebSync no debe esperar el resultado final. Dentro del llamador (el controlador de eventos en este ejemplo), se repite el proceso. El llamador puede hacer otro trabajo que no depende del resultado de AccessTheWebAsync antes de aguardar ese resultado, o es posible que el llamador aguardar inmediatamente. Cuando el controlador de eventos alcanza una expresión de aguardar, la aplicación se centra en la finalización de GetStringAsync. El controlador de eventos está esperando AccessTheWebAsync, y AccessTheWebAsync está esperando GetStringAsync. -
GetStringAsync completa y genera un resultado de la cadena. El resultado de la cadena no es devuelto por la llamada a GetStringAsync de la manera que cabría esperar. Recuerde que el método devuelve ya una tarea en el paso 3). Instead, la cadena se almacena en la tarea que representa el método, getStringTask. El operador aguardar recupera el resultado de getStringTask. La instrucción de asignación asigna el resultado recuperado a urlContents. -
Cuando AccessTheWebAsync tiene el resultado de la cadena, el método puede calcular la longitud de la cadena. El trabajo de AccessTheWebAsync también se completa, y el controlador de eventos que espera puede reanudar. En el ejemplo completo en el final de este tema, puede comprobar que el controlador de eventos recupera e imprime el valor de resultado de longitud.
-
El método marcado async puede utilizar Espera o espera para notificar los puntos de suspensión. El operador aguardar indica al compilador que el método async no pueda continuar último que señala hasta que se complete el proceso aguardado asincrónico. Mientras tanto, el control vuelve al llamador del método async. La suspensión de un método async en una expresión de aguardar no constituye a una salida de método, y los bloques de finally no se ejecutan. -
El método marcado se puede propio async aguardar por los métodos que lo llama.
// Signature specifies Task<TResult> async Task<int> TaskOfTResult_MethodAsync() { int hours; // . . . // Return statement specifies an integer result. return hours; } // Calls to TaskOfTResult_MethodAsync Task<int> returnedTaskTResult = TaskOfTResult_MethodAsync(); int intResult = await returnedTaskTResult; // or, in a single statement int intResult = await TaskOfTResult_MethodAsync(); // Signature specifies Task async Task Task_MethodAsync() { // . . . // The method has no return statement. } // Calls to Task_MethodAsync Task returnedTask = Task_MethodAsync(); await returnedTask; // or, in a single statement await Task_MethodAsync();
IAsyncOperation, que corresponde a Task<TResult> IAsyncAction, que corresponde a Task
|
|
|
|
|---|---|---|
|
Walkthrough: Acceso a web usando Async y Await (C# y Visual Basic) |
|
Ejemplo Async: Obtener acceso al tutorial web (C# y Visual Basic) |
|
Cómo: Ampliar el tutorial usando Task.WhenAll (C# y Visual Basic) |
|
|
|
Cómo: Hacer varias solicitudes web en paralelo (C# y Visual Basic) |
|
Ejemplo Async: Haga Varias solicitudes web en paralelo (C# y Visual Basic) |
|
|
|
|
|
Flujo de control en programas asincrónicos (C# y Visual Basic) |
|
Ejemplo Async: Flujo de control en programas Async (C# y Visual Basic) |
|
|
Ejemplo Async: Ajustando la aplicación de (C# y Visual Basic) |
|
|
Controlar cómo se vuelve a entrar en aplicaciones asincrónicas (C# y Visual Basic) |
|
|
|
WhenAny: Puente entre .NET Framework y Windows en tiempo de ejecución (C# y Visual Basic) |
|
Ejemplo Async: Puente entre .NET y el tiempo de ejecución de Windows (AsTask y WhenAny) |
|
Cancelación: Puente entre .NET Framework y Windows en tiempo de ejecución (C# y Visual Basic) |
|
Ejemplo Async: Puente entre .NET y el tiempo de ejecución de Windows (AsTask y Cancelación) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Programación asincrónica (aplicaciones de almacén de Windows) |
|
|
|
|
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; // Add a using directive and a reference for System.Net.Http; using System.Net.Http; namespace AsyncFirstExample { public partial class MainWindow : Window { // Mark the event handler with async so you can use await in it. private async void StartButton_Click(object sender, RoutedEventArgs e) { // Call and await separately. //Task<int> getLengthTask = AccessTheWebAsync(); //// You can do independent work here. //int contentLength = await getLengthTask; int contentLength = await AccessTheWebAsync(); resultsTextBox.Text += String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength); } // Three things to note in the signature: // - The method has an async modifier. // - The return type is Task or Task<T>. (See "Return Types" section.) // Here, it is Task<int> because the return statement returns an integer. // - The method name ends in "Async." async Task<int> AccessTheWebAsync() { // You need to add a reference to System.Net.Http to declare client. HttpClient client = new HttpClient(); // GetStringAsync returns a Task<string>. That means that when you await the // task you'll get a string (urlContents). Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com"); // You can do work here that doesn't rely on the string from GetStringAsync. DoIndependentWork(); // The await operator suspends AccessTheWebAsync. // - AccessTheWebAsync can't continue until getStringTask is complete. // - Meanwhile, control returns to the caller of AccessTheWebAsync. // - Control resumes here when getStringTask is complete. // - The await operator then retrieves the string result from getStringTask. string urlContents = await getStringTask; // The return statement specifies an integer result. // Any methods that are awaiting AccessTheWebAsync retrieve the length value. return urlContents.Length; } void DoIndependentWork() { resultsTextBox.Text += "Working . . . . . . .\r\n"; } } } // Sample Output: // Working . . . . . . . // Length of the downloaded string: 41564.