Usar métodos asincrónicos en ASP.NET 4.5Using Asynchronous Methods in ASP.NET 4.5

by Rick Andersonby Rick Anderson

Este tutorial le enseñará los aspectos básicos de creación de una aplicación de formularios Web Forms ASP.NET asincrónico con Visual Studio Express 2012 para Web, que es una versión gratuita de Microsoft Visual Studio.This tutorial will teach you the basics of building an asynchronous ASP.NET Web Forms application using Visual Studio Express 2012 for Web, which is a free version of Microsoft Visual Studio. También puede usar Visual Studio 2012.You can also use Visual Studio 2012. Las secciones siguientes se incluyen en este tutorial.The following sections are included in this tutorial.

Se proporciona un ejemplo completo para este tutorial enA complete sample is provided for this tutorial at
https://github.com/RickAndMSFT/Async-ASP.NET/ en el GitHub sitio.https://github.com/RickAndMSFT/Async-ASP.NET/ on the GitHub site.

Las páginas Web ASP.NET 4.5 en combinación .NET 4.5 permite registrar los métodos asincrónicos que devuelven un objeto de tipo tarea.ASP.NET 4.5 Web Pages in combination .NET 4.5 enables you to register asynchronous methods that return an object of type Task. .NET Framework 4 introdujo un concepto de programación asincrónico se denomina un tarea y ASP.NET 4.5 admite tarea.The .NET Framework 4 introduced an asynchronous programming concept referred to as a Task and ASP.NET 4.5 supports Task. Las tareas se representan mediante el tarea tipo y los tipos relacionados en el System.Threading.Tasks espacio de nombres.Tasks are represented by the Task type and related types in the System.Threading.Tasks namespace. .NET Framework 4.5 se basa en esta compatibilidad asincrónica con el await y async palabras clave que facilitan el trabajo con tarea objetos mucho menos complejos que la anterior métodos asincrónicos.The .NET Framework 4.5 builds on this asynchronous support with the await and async keywords that make working with Task objects much less complex than previous asynchronous approaches. El await palabra clave es la forma abreviada sintáctica presente para indicar que un fragmento de código debe esperar asincrónicamente en algún otro elemento de código.The await keyword is syntactical shorthand for indicating that a piece of code should asynchronously wait on some other piece of code. El async palabra clave representa una sugerencia que puede usar para marcar métodos como métodos asincrónicos basados en tareas.The async keyword represents a hint that you can use to mark methods as task-based asynchronous methods. La combinación de await, asyncy el tarea objeto facilita en gran medida para que pueda escribir código asincrónico en .NET 4.5.The combination of await, async, and the Task object makes it much easier for you to write asynchronous code in .NET 4.5. El nuevo modelo para los métodos asincrónicos se denomina el modelo asincrónico basado en tareas (pulse).The new model for asynchronous methods is called the Task-based Asynchronous Pattern (TAP). En este tutorial se da por supuesto que tiene cierta familiaridad con el uso de programación asincrónica await y async palabras clave y el tarea espacio de nombres.This tutorial assumes you have some familiarity with asynchronous programing using await and async keywords and the Task namespace.

Para obtener más información sobre el uso de la await y async palabras clave y el tarea espacio de nombres, vea las siguientes referencias.For more information on the using await and async keywords and the Task namespace, see the following references.

Cómo se procesan las solicitudes por el grupo de subprocesosHow Requests Are Processed by the Thread Pool

En el servidor web, .NET Framework mantiene un grupo de subprocesos que se usan para atender las solicitudes ASP.NET.On the web server, the .NET Framework maintains a pool of threads that are used to service ASP.NET requests. Cuando llega una solicitud, se envía un subproceso del grupo para procesar la solicitud.When a request arrives, a thread from the pool is dispatched to process that request. Si la solicitud se procesa de forma sincrónica, el subproceso que procesa la solicitud está ocupado mientras la solicitud se está procesando y que el subproceso no puede atender otra solicitud.If the request is processed synchronously, the thread that processes the request is busy while the request is being processed, and that thread cannot service another request.

Esto podría no ser un problema, ya que se pueden hacer lo suficientemente grande como para dar cabida a muchos subprocesos ocupados del grupo de subprocesos.This might not be a problem, because the thread pool can be made large enough to accommodate many busy threads. Sin embargo, se limita el número de subprocesos en el grupo de subprocesos (el valor máximo predeterminado de .NET 4.5 es 5000).However, the number of threads in the thread pool is limited (the default maximum for .NET 4.5 is 5,000). En aplicaciones de gran tamaño con la simultaneidad alto de solicitudes de ejecución prolongada, todos los subprocesos disponibles podrían estar ocupados.In large applications with high concurrency of long-running requests, all available threads might be busy. Esta condición se conoce como la falta de subprocesos.This condition is known as thread starvation. Cuando se alcanza esta condición, el servidor web pone en cola las solicitudes.When this condition is reached, the web server queues requests. Si la cola de solicitudes se llena, el servidor web rechaza las solicitudes con el estado HTTP 503 (Server Too Busy).If the request queue becomes full, the web server rejects requests with an HTTP 503 status (Server Too Busy). El grupo de subprocesos CLR tiene limitaciones en las inyecciones de subproceso nuevo.The CLR thread pool has limitations on new thread injections. Si la simultaneidad es por ráfagas (es decir, el sitio web, de repente, puede obtener un gran número de solicitudes) y todos los subprocesos de solicitud disponibles están ocupados debido a llamadas de back-end con una latencia elevada, la tasa de inserción de subproceso limitado puede hacer que la aplicación responda muy mal.If concurrency is bursty (that is, your web site can suddenly get a large number of requests) and all available request threads are busy because of backend calls with high latency, the limited thread injection rate can make your application respond very poorly. Además, cada subproceso nuevo agregado al grupo de subprocesos tiene sobrecarga (por ejemplo, 1 MB de memoria de pila).Additionally, each new thread added to the thread pool has overhead (such as 1 MB of stack memory). Una aplicación web mediante los métodos sincrónicos a las llamadas de alta latencia de servicio donde el grupo de subprocesos aumenta con el valor predeterminado de .NET 4.5 admite un máximo de 5 000 subprocesos consumiría aproximadamente 5 GB más memoria que una aplicación que pueda el servicio de la misma solicitudes con los métodos asincrónicos y solo 50 subprocesos.A web application using synchronous methods to service high latency calls where the thread pool grows to the .NET 4.5 default maximum of 5, 000 threads would consume approximately 5 GB more memory than an application able the service the same requests using asynchronous methods and only 50 threads. Cuando está realizando trabajo asincrónico, no siempre usa un subproceso.When you're doing asynchronous work, you're not always using a thread. Por ejemplo, al realizar una solicitud de servicio web asincrónico, ASP.NET no usará los subprocesos entre el async llamada al método y el await.For example, when you make an asynchronous web service request, ASP.NET will not be using any threads between the async method call and the await. Usar el grupo de subprocesos para atender las solicitudes con una latencia elevada puede dar lugar a una superficie de memoria grande y una mala utilización del hardware del servidor.Using the thread pool to service requests with high latency can lead to a large memory footprint and poor utilization of the server hardware.

Procesar solicitudes asincrónicasProcessing Asynchronous Requests

En las aplicaciones web que aparece un gran número de solicitudes simultáneas en el inicio o que tenga una carga por ráfagas (donde simultaneidad aumenta repentinamente), realizar llamadas al servicio web asincrónico, aumentará la capacidad de respuesta de la aplicación.In web applications that see a large number of concurrent requests at start-up or has a bursty load (where concurrency increases suddenly), making web service calls asynchronous will increase the responsiveness of your application. Una solicitud asincrónica tarda la misma cantidad de tiempo en procesarse que una solicitud sincrónica.An asynchronous request takes the same amount of time to process as a synchronous request. Por ejemplo, si una solicitud realiza un servicio web de llamada requiere dos segundos en completarse, la solicitud tardará dos segundos si se realiza de forma sincrónica o asincrónica.For example, if a request makes a web service call that requires two seconds to complete, the request takes two seconds whether it is performed synchronously or asynchronously. Sin embargo, durante una llamada asincrónica, no se bloquea un subproceso deja de responder a otras solicitudes mientras espera a que finalice la primera solicitud.However, during an asynchronous call, a thread is not blocked from responding to other requests while it waits for the first request to complete. Por lo tanto, las solicitudes asincrónicas evitar el crecimiento de grupo de puesta en cola y el subproceso de solicitud cuando hay muchas solicitudes simultáneas que invocan las operaciones de larga ejecución.Therefore, asynchronous requests prevent request queuing and thread pool growth when there are many concurrent requests that invoke long-running operations.

Elegir los métodos sincrónicos o asincrónicosChoosing Synchronous or Asynchronous Methods

Esta sección enumeran las directrices sobre cuándo usar métodos sincrónicos o asincrónicos.This section lists guidelines for when to use synchronous or asynchronous Methods. Se trata de meras directrices; Examine individualmente cada aplicación para determinar si los métodos asincrónicos ayudar con el rendimiento.These are just guidelines; examine each application individually to determine whether asynchronous methods help with performance.

En general, use los métodos sincrónicos para las condiciones siguientes:In general, use synchronous methods for the following conditions:

  • Las operaciones son simples o de ejecución breve.The operations are simple or short-running.
  • La simplicidad es más importante que la eficacia.Simplicity is more important than efficiency.
  • Las operaciones son principalmente operaciones de la CPU en lugar de las operaciones que implican una amplia disco o una sobrecarga de la red.The operations are primarily CPU operations instead of operations that involve extensive disk or network overhead. Usar métodos asincrónicos en operaciones relacionadas con la CPU no proporciona ninguna ventaja y da lugar a mayor sobrecarga.Using asynchronous methods on CPU-bound operations provides no benefits and results in more overhead.

En general, utilice los métodos asincrónicos para las condiciones siguientes:In general, use asynchronous methods for the following conditions:

  • Se están llamando a los servicios que se pueden consumir mediante los métodos asincrónicos, y usa .NET 4.5 o superior.You're calling services that can be consumed through asynchronous methods, and you're using .NET 4.5 or higher.

  • Las operaciones son enlazada a la red o puedo enlazadas en lugar de a la CPU.The operations are network-bound or I/O-bound instead of CPU-bound.

  • El paralelismo es más importante que la simplicidad de código.Parallelism is more important than simplicity of code.

  • Desea proporcionar un mecanismo que permite a los usuarios cancelar una solicitud de ejecución prolongada.You want to provide a mechanism that lets users cancel a long-running request.

  • Cuando la ventaja de la conmutación de subprocesos supera el costo de cambiar el contexto.When the benefit of switching threads outweighs the cost of the context switch. En general, debe convertir un método asincrónico si el método sincrónico bloquea el subproceso de solicitud ASP.NET mientras no se realiza ningún trabajo.In general, you should make a method asynchronous if the synchronous method blocks the ASP.NET request thread while doing no work. Al realizar la llamada asincrónica, el subproceso de solicitud ASP.NET no está bloqueado realizando ningún trabajo mientras espera a que finalice la solicitud de servicio web.By making the call asynchronous, the ASP.NET request thread is not blocked doing no work while it waits for the web service request to complete.

  • Las pruebas muestran que las operaciones bloqueos son un cuello de botella de rendimiento del sitio y que IIS puede atender más solicitudes mediante el uso de métodos asincrónicos para estas llamadas bloqueos.Testing shows that the blocking operations are a bottleneck in site performance and that IIS can service more requests by using asynchronous methods for these blocking calls.

    El ejemplo descargable muestra cómo utilizar los métodos asincrónicos de forma eficaz.The downloadable sample shows how to use asynchronous methods effectively. El ejemplo proporcionado se diseñó para proporcionar una simple demostración de la programación asincrónica en ASP.NET 4.5.The sample provided was designed to provide a simple demonstration of asynchronous programming in ASP.NET 4.5. El ejemplo no pretende ser una arquitectura de referencia para la programación asincrónica en ASP.NET.The sample is not intended to be a reference architecture for asynchronous programming in ASP.NET. El programa de ejemplo llama a ASP.NET Web API métodos que a su vez llaman a Task.Delay para simular las llamadas al servicio web de ejecución prolongada.The sample program calls ASP.NET Web API methods which in turn call Task.Delay to simulate long-running web service calls. La mayoría de las aplicaciones de producción no mostrarán ventajas tan evidentes al usar métodos asincrónicos.Most production applications will not show such obvious benefits to using asynchronous Methods.

Pocas aplicaciones exigen que todos los métodos sea asincrónico.Few applications require all methods to be asynchronous. A menudo, proporciona la máxima eficacia para la cantidad de trabajo necesario convertir algunos métodos sincrónicos en métodos asincrónicos.Often, converting a few synchronous methods to asynchronous methods provides the best efficiency increase for the amount of work required.

La aplicación de ejemploThe Sample Application

Puede descargar la aplicación de ejemplo de https://github.com/RickAndMSFT/Async-ASP.NET en el GitHub sitio.You can download the sample application from https://github.com/RickAndMSFT/Async-ASP.NET on the GitHub site. El repositorio consta de tres proyectos:The repository consists of three projects:

  • WebAppAsync: El proyecto de formularios Web Forms de ASP.NET que utiliza la API Web WebAPIpwg service.WebAppAsync: The ASP.NET Web Forms project that consumes the Web API WebAPIpwg service. La mayoría del código para este tutorial es desde este proyecto.Most of the code for this tutorial is from the this project.
  • WebAPIpgw: El proyecto de ASP.NET MVC 4 Web API que implementa el Products, Gizmos and Widgets controladores.WebAPIpgw: The ASP.NET MVC 4 Web API project that implements the Products, Gizmos and Widgets controllers. Proporciona los datos para el WebAppAsync proyecto y el Mvc4Async proyecto.It provides the data for the WebAppAsync project and the Mvc4Async project.
  • Mvc4Async: El proyecto de ASP.NET MVC 4 que contiene el código usado en otro tutorial.Mvc4Async: The ASP.NET MVC 4 project that contains the code used in another tutorial. Realiza llamadas de API Web a la WebAPIpwg service.It makes Web API calls to the WebAPIpwg service.

La página sincrónica GizmosThe Gizmos Synchronous Page

El código siguiente muestra el Page_Load método sincrónico que se usa para mostrar una lista de gizmos.The following code shows the Page_Load synchronous method that is used to display a list of gizmos. (En este artículo, un artículo tiene un es un dispositivo mecánico ficticio).(For this article, a gizmo is a fictional mechanical device.)

public partial class Gizmos : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        var gizmoService = new GizmoService();
        GizmoGridView.DataSource = gizmoService.GetGizmos();
        GizmoGridView.DataBind();
    }
}

El código siguiente muestra el GetGizmos método del artículo tiene un servicio.The following code shows the GetGizmos method of the gizmo service.

public class GizmoService
{
    public async Task<List<Gizmo>> GetGizmosAsync(
        // Implementation removed.
       
    public List<Gizmo> GetGizmos()
    {
        var uri = Util.getServiceUri("Gizmos");
        using (WebClient webClient = new WebClient())
        {
            return JsonConvert.DeserializeObject<List<Gizmo>>(
                webClient.DownloadString(uri)
            );
        }
    }
}

El GizmoService GetGizmos método pasa un URI a un servicio ASP.NET Web API HTTP que devuelve una lista de los datos gizmos.The GizmoService GetGizmos method passes a URI to an ASP.NET Web API HTTP service which returns a list of gizmos data. El WebAPIpgw proyecto contiene la implementación de la API Web gizmos, widget y product controladores.The WebAPIpgw project contains the implementation of the Web API gizmos, widget and product controllers.
La siguiente imagen muestra la página gizmos desde el proyecto de ejemplo.The following image shows the gizmos page from the sample project.

Gizmos

Creación de una página asincrónica GizmosCreating an Asynchronous Gizmos Page

El ejemplo usa el nuevo async y await palabras clave (disponibles en .NET 4.5 y Visual Studio 2012) para permitir que el compilador ser responsable de mantener las complicadas transformaciones necesarias para programación asincrónica.The sample uses the new async and await keywords (available in .NET 4.5 and Visual Studio 2012) to let the compiler be responsible for maintaining the complicated transformations necessary for asynchronous programming. El compilador le permite escribir código mediante que construcciones de flujo de control sincrónico de la de C# y el compilador aplica automáticamente las transformaciones necesarias para utilizar devoluciones de llamada con el fin de evitar el bloqueo de subprocesos.The compiler lets you write code using the C#'s synchronous control flow constructs and the compiler automatically applies the transformations necessary to use callbacks in order to avoid blocking threads.

Páginas asincrónicas de ASP.NET deben incluir el página la directiva con la Async atributo establecido en "true".ASP.NET asynchronous pages must include the Page directive with the Async attribute set to "true". El siguiente código muestra la página la directiva con la Async atributo establecido en "true" para el GizmosAsync.aspx página.The following code shows the Page directive with the Async attribute set to "true" for the GizmosAsync.aspx page.

<%@ Page Async="true"  Language="C#" AutoEventWireup="true" 
    CodeBehind="GizmosAsync.aspx.cs" Inherits="WebAppAsync.GizmosAsync" %>

El siguiente código muestra la Gizmos sincrónica Page_Load método y el GizmosAsync página asincrónica.The following code shows the Gizmos synchronous Page_Load method and the GizmosAsync asynchronous page. Si el explorador admite el HTML 5 <marcar> elemento, verá los cambios en GizmosAsync en amarillo resaltado.If your browser supports the HTML 5 <mark> element, you'll see the changes in GizmosAsync in yellow highlight.

protected void Page_Load(object sender, EventArgs e)
{
   var gizmoService = new GizmoService();
   GizmoGridView.DataSource = gizmoService.GetGizmos();
   GizmoGridView.DataBind();
}

La versión asincrónica:The asynchronous version:

protected void Page_Load(object sender, EventArgs e)
{
    RegisterAsyncTask(new PageAsyncTask(GetGizmosSvcAsync));
}

private async Task GetGizmosSvcAsync()
{
    var gizmoService = new GizmoService();
    GizmosGridView.DataSource = await gizmoService.GetGizmosAsync();
    GizmosGridView.DataBind();
}

Se aplicaron los cambios siguientes para permitir la GizmosAsync página sea asincrónico.The following changes were applied to allow the GizmosAsync page be asynchronous.

  • El página la directiva debe tener el Async atributo establecido en "true".The Page directive must have the Async attribute set to "true".
  • El RegisterAsyncTask método se usa para registrar una tarea asincrónica que contiene el código que se ejecuta de forma asincrónica.The RegisterAsyncTask method is used to register an asynchronous task containing the code which runs asynchronously.
  • El nuevo GetGizmosSvcAsync método está marcado con el async palabra clave, que indica al compilador que genere devoluciones de llamada para partes del cuerpo y crear automáticamente un Task que se devuelve.The new GetGizmosSvcAsync method is marked with the async keyword, which tells the compiler to generate callbacks for parts of the body and to automatically create a Task that is returned.
  • "Async" se anexa al nombre del método asincrónico."Async" was appended to the asynchronous method name. Anexa "Async" no es necesario, pero es la convención al escribir métodos asincrónicos.Appending "Async" is not required but is the convention when writing asynchronous methods.
  • El tipo de valor devuelto de la nueva GetGizmosSvcAsync método es Task.The return type of the new GetGizmosSvcAsync method is Task. El tipo de valor devuelto de Task representa el trabajo en curso y proporciona a los llamadores del método con un identificador a través de la que se va a esperar la finalización de la operación asincrónica.The return type of Task represents ongoing work and provides callers of the method with a handle through which to wait for the asynchronous operation's completion.
  • El await palabra clave se aplicó a la llamada al servicio web.The await keyword was applied to the web service call.
  • Se llamó a la API del servicio web asincrónico (GetGizmosAsync).The asynchronous web service API was called (GetGizmosAsync).

Dentro de la GetGizmosSvcAsync otro método asincrónico, de cuerpo de método GetGizmosAsync se llama.Inside of the GetGizmosSvcAsync method body another asynchronous method, GetGizmosAsync is called. GetGizmosAsync se devuelve inmediatamente un Task<List<Gizmo>> que finalmente se completará cuando los datos están disponibles.GetGizmosAsync immediately returns a Task<List<Gizmo>> that will eventually complete when the data is available. Dado que no desea hacer nada más hasta que tenga los datos de artículo tiene un, el código espera la tarea (mediante el await palabra clave).Because you don't want to do anything else until you have the gizmo data, the code awaits the task (using the await keyword). Puede usar el await palabra clave solo en los métodos anotados con el async palabra clave.You can use the await keyword only in methods annotated with the async keyword.

El await palabra clave no bloquea el subproceso hasta que se complete la tarea.The await keyword does not block the thread until the task is complete. El resto del método se registra como devolución de llamada en la tarea y se devuelve inmediatamente.It signs up the rest of the method as a callback on the task, and immediately returns. Cuando finaliza la tarea en espera, se invocan esa devolución de llamada y, por tanto, reanudar la ejecución de la derecha del método donde se quedó.When the awaited task eventually completes, it will invoke that callback and thus resume the execution of the method right where it left off. Para obtener más información sobre el uso de la await y async palabras clave y el tarea espacio de nombres, vea el async referencias.For more information on using the await and async keywords and the Task namespace, see the async references.

El siguiente código muestra la GetGizmos y GetGizmosAsync métodos.The following code shows the GetGizmos and GetGizmosAsync methods.

public List<Gizmo> GetGizmos()
{
    var uri = Util.getServiceUri("Gizmos");
    using (WebClient webClient = new WebClient())
    {
        return JsonConvert.DeserializeObject<List<Gizmo>>(
            webClient.DownloadString(uri)
        );
    }
}
public async Task<List<Gizmo>> GetGizmosAsync()
{
    var uri = Util.getServiceUri("Gizmos");
    using (WebClient webClient = new WebClient())
    {
        return JsonConvert.DeserializeObject<List<Gizmo>>(
            await webClient.DownloadStringTaskAsync(uri)
        );
    }
}

Los cambios asincrónicos son similares a los realizados en el GizmosAsync anteriormente.The asynchronous changes are similar to those made to the GizmosAsync above.

  • La firma del método se anota con el async palabra clave, el tipo de valor devuelto se cambió a Task<List<Gizmo>>, y Async se anexa al nombre del método.The method signature was annotated with the async keyword, the return type was changed to Task<List<Gizmo>>, and Async was appended to the method name.
  • Asincrónico HttpClient clase se utiliza en lugar de sincrónico WebClient clase.The asynchronous HttpClient class is used instead of the synchronous WebClient class.
  • El await palabra clave se aplicó a la HttpClientGetAsync método asincrónico.The await keyword was applied to the HttpClientGetAsync asynchronous method.

La siguiente imagen muestra la vista asincrónica artículo tiene un.The following image shows the asynchronous gizmo view.

async

La presentación de los exploradores de los datos gizmos es idéntica a la vista creada por la llamada sincrónica.The browsers presentation of the gizmos data is identical to the view created by the synchronous call. La única diferencia es que la versión asincrónica puede ser un mejor rendimiento con cargas pesadas.The only difference is the asynchronous version may be more performant under heavy loads.

Notas de RegisterAsyncTaskRegisterAsyncTask Notes

Los métodos que se enlazan con RegisterAsyncTask se ejecutará inmediatamente después de PreRender.Methods hooked up with RegisterAsyncTask will run immediately after PreRender. También puede usar eventos de async void página directamente, como se muestra en el código siguiente:You can also use async void page events directly, as shown in the following code:

protected async void Page_Load(object sender, EventArgs e) {
    await ...;
    // do work
}

La desventaja de async void eventos es que los desarrolladores ya no tiene control total sobre cuándo ejecutan eventos.The downside to async void events is that developers no longer has full control over when events execute. Por ejemplo, si ambos .aspx y. Definir master Page_Load eventos y uno o ambos son asincrónicas, no se puede garantizar el orden de ejecución.For example, if both an .aspx and a .Master define Page_Load events and one or both of them are asynchronous, the order of execution can't be guaranteed. El mismo orden indeterminiate para controladores de eventos que no sean (como async void Button_Click ) se aplica.The same indeterminiate order for non event handlers (such as async void Button_Click ) applies. Para la mayoría de los desarrolladores, esto debe ser aceptable, pero solo aquellos que requieren un control total sobre el orden de ejecución deben usar las API como RegisterAsyncTask que consumen los métodos que devuelven un objeto de tarea.For most developers this should be acceptable, but those who require full control over the order of execution should only use APIs like RegisterAsyncTask that consume methods which return a Task object.

Realizar varias operaciones en paraleloPerforming Multiple Operations in Parallel

Los métodos asincrónicos tienen una ventaja significativa sobre los métodos sincrónicos cuando una acción debe realizar varias operaciones independientes.Asynchronous Methods have a significant advantage over synchronous methods when an action must perform several independent operations. En el ejemplo proporcionado, la página sincrónica PWG.aspx(para los productos, Widgets y Gizmos) muestra los resultados de tres llamadas al servicio web para obtener una lista de productos, widgets y gizmos.In the sample provided, the synchronous page PWG.aspx(for Products, Widgets and Gizmos) displays the results of three web service calls to get a list of products, widgets, and gizmos. El ASP.NET Web API proyecto que proporciona estos servicios usa Task.Delay para simular la red lenta o latencia de llamadas.The ASP.NET Web API project that provides these services uses Task.Delay to simulate latency or slow network calls. Cuando se establece el retraso de 500 milisegundos, asincrónicos PWGasync.aspx página tarda un poco más de 500 milisegundos en completarse mientras sincrónico PWG versión asume 1.500 milisegundos.When the delay is set to 500 milliseconds, the asynchronous PWGasync.aspx page takes a little over 500 milliseconds to complete while the synchronous PWG version takes over 1,500 milliseconds. Sincrónico PWG.aspx página se muestra en el código siguiente.The synchronous PWG.aspx page is shown in the following code.

protected void Page_Load(object sender, EventArgs e)
{
    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();

    var widgetService = new WidgetService();
    var prodService = new ProductService();
    var gizmoService = new GizmoService();

    var pwgVM = new ProdGizWidgetVM(
        widgetService.GetWidgets(),
        prodService.GetProducts(),
        gizmoService.GetGizmos()
       );
    WidgetGridView.DataSource = pwgVM.widgetList;
    WidgetGridView.DataBind();
    ProductGridView.DataSource = pwgVM.prodList;
    ProductGridView.DataBind();
    GizmoGridView.DataSource = pwgVM.gizmoList;
    GizmoGridView.DataBind();

    stopWatch.Stop();
    ElapsedTimeLabel.Text = String.Format("Elapsed time: {0}", 
        stopWatch.Elapsed.Milliseconds / 1000.0);
}

Asincrónico PWGasync código subyacente se muestra a continuación.The asynchronous PWGasync code behind is shown below.

protected void Page_Load(object sender, EventArgs e)
{
    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();
    RegisterAsyncTask(new PageAsyncTask(GetPWGsrvAsync));
    stopWatch.Stop();
    ElapsedTimeLabel.Text = String.Format("Elapsed time: {0}",
        stopWatch.Elapsed.Milliseconds / 1000.0);
}

private async Task GetPWGsrvAsync()
{
    var widgetService = new WidgetService();
    var prodService = new ProductService();
    var gizmoService = new GizmoService();

    var widgetTask = widgetService.GetWidgetsAsync();
    var prodTask = prodService.GetProductsAsync();
    var gizmoTask = gizmoService.GetGizmosAsync();

    await Task.WhenAll(widgetTask, prodTask, gizmoTask);

    var pwgVM = new ProdGizWidgetVM(
       widgetTask.Result,
       prodTask.Result,
       gizmoTask.Result
       );

    WidgetGridView.DataSource = pwgVM.widgetList;
    WidgetGridView.DataBind();
    ProductGridView.DataSource = pwgVM.prodList;
    ProductGridView.DataBind();
    GizmoGridView.DataSource = pwgVM.gizmoList;
    GizmoGridView.DataBind();           
}

La siguiente imagen muestra la vista devuelta por la asincrónica PWGasync.aspx página.The following image shows the view returned from the asynchronous PWGasync.aspx page.

Uso de un Token de cancelaciónUsing a Cancellation Token

Los métodos asincrónicos que devuelven Taskson cancelable, que se toman un CancellationToken parámetro cuando se proporciona con el AsyncTimeout atributo de la página directiva.Asynchronous Methods returning Taskare cancelable, that is they take a CancellationToken parameter when one is provided with the AsyncTimeout attribute of the Page directive. El siguiente código muestra la GizmosCancelAsync.aspx página con un tiempo de espera de segundo.The following code shows the GizmosCancelAsync.aspx page with a timeout of on second.

<%@ Page  Async="true"  AsyncTimeout="1" 
    Language="C#" AutoEventWireup="true" 
    CodeBehind="GizmosCancelAsync.aspx.cs" 
    Inherits="WebAppAsync.GizmosCancelAsync" %>

El siguiente código muestra la GizmosCancelAsync.aspx.cs archivo.The following code shows the GizmosCancelAsync.aspx.cs file.

protected void Page_Load(object sender, EventArgs e)
{
    RegisterAsyncTask(new PageAsyncTask(GetGizmosSvcCancelAsync));
}

private async Task GetGizmosSvcCancelAsync(CancellationToken cancellationToken)
{
    var gizmoService = new GizmoService();
    var gizmoList = await gizmoService.GetGizmosAsync(cancellationToken);
    GizmosGridView.DataSource = gizmoList;
    GizmosGridView.DataBind();
}
private void Page_Error(object sender, EventArgs e)
{
    Exception exc = Server.GetLastError();

    if (exc is TimeoutException)
    {
        // Pass the error on to the Timeout Error page
        Server.Transfer("TimeoutErrorPage.aspx", true);
    }
}

En la aplicación de ejemplo proporcionada, seleccionando la GizmosCancelAsync vincular llamadas la GizmosCancelAsync.aspx página y muestra la cancelación (por tiempo de espera) de la llamada asincrónica.In the sample application provided, selecting the GizmosCancelAsync link calls the GizmosCancelAsync.aspx page and demonstrates the cancellation (by timing out) of the asynchronous call. Dado que es el tiempo de retraso dentro de un intervalo aleatorio, necesita actualizar la página de un par de veces para obtener el mensaje de error de tiempo de espera.Because the delay time is within a random range, you might need to refresh the page a couple times to get the time out error message.

Configuración del servidor para llamadas de servicio Web de alta simultaneidad y alta latenciaServer Configuration for High Concurrency/High Latency Web Service Calls

Para obtener los beneficios de una aplicación web asincrónica, es posible que deba realizar algunos cambios en la configuración predeterminada del servidor.To realize the benefits of an asynchronous web application, you might need to make some changes to the default server configuration. Tenga en cuenta al configurar y probar la aplicación web asíncronos de esfuerzo lo siguiente.Keep the following in mind when configuring and stress testing your asynchronous web application.

  • Windows 7, Windows Vista, Windows 8 y todos los sistemas operativos de cliente de Windows tiene un máximo de 10 solicitudes simultáneas.Windows 7, Windows Vista, Window 8, and all Windows client operating systems have a maximum of 10 concurrent requests. Necesitará un sistema operativo de Windows Server para ver las ventajas de los métodos asincrónicos con una carga elevada.You'll need a Windows Server operating system to see the benefits of asynchronous methods under high load.

  • Registrar .NET 4.5 con IIS desde un símbolo con privilegios elevados mediante el comando siguiente:Register .NET 4.5 with IIS from an elevated command prompt using the following command:
    %windir%\Microsoft.NET\Framework64 \v4.0.30319\aspnet_regiis -i.%windir%\Microsoft.NET\Framework64 \v4.0.30319\aspnet_regiis -i
    Consulte herramienta de registro de IIS en ASP.NET (Aspnet_regiis.exe)See ASP.NET IIS Registration Tool (Aspnet_regiis.exe)

  • Es posible que deba aumentar el HTTP.sys límite de la cola desde el valor predeterminado de 1.000 a 5.000.You might need to increase the HTTP.sys queue limit from the default value of 1,000 to 5,000. Si el valor es demasiado bajo, es posible que vea HTTP.sys rechazar las solicitudes con el estado HTTP 503.If the setting is too low, you may see HTTP.sys reject requests with a HTTP 503 status. Para cambiar el límite de cola de HTTP.sys:To change the HTTP.sys queue limit:

    • Abra el Administrador de IIS y navegue hasta el panel grupos de aplicaciones.Open IIS manager and navigate to the Application Pools pane.
    • Haga clic con el botón derecho en el grupo de aplicaciones de destino y seleccione configuración avanzada.Right click on the target application pool and select Advanced Settings.
      advancedadvanced
    • En el configuración avanzada cuadro de diálogo, cambie longitud de cola de 1.000 a 5.000.In the Advanced Settings dialog box, change Queue Length from 1,000 to 5,000.
      Longitud de colaQueue length

    Tenga en cuenta que en las imágenes anteriores, .NET framework se incluye como v4.0, aunque el grupo de aplicaciones es usar .NET 4.5.Note in the images above, the .NET framework is listed as v4.0, even though the application pool is using .NET 4.5. Para entender esta discrepancia, consulte lo siguiente:To understand this discrepancy, see the following:

  • Control de versiones de .NET y .NET Framework 4.5 Multi-Targeting - es una actualización en contexto a .NET 4.0.NET Versioning and Multi-Targeting - .NET 4.5 is an in-place upgrade to .NET 4.0

  • Establecimiento de una aplicación IIS o grupo de aplicaciones para usar ASP.NET 3.5, en lugar de 2.0How to set an IIS Application or AppPool to use ASP.NET 3.5 rather than 2.0

  • Versiones y dependencias de .NET Framework.NET Framework Versions and Dependencies

  • Si la aplicación está utilizando servicios web o System.NET para comunicarse con un back-end a través de HTTP que necesite aumentar la connectionManagement/maxconnection elemento.If your application is using web services or System.NET to communicate with a backend over HTTP you may need to increase the connectionManagement/maxconnection element. Para las aplicaciones de ASP.NET, esto está limitado por la característica de configuración automática para 12 veces el número de CPU.For ASP.NET applications, this is limited by the autoConfig feature to 12 times the number of CPUs. Esto significa que en cuádruple, puede tener como máximo 12 * 4 = 48 conexiones simultáneas a un punto de conexión IP.That means that on a quad-proc, you can have at most 12 * 4 = 48 concurrent connections to an IP end point. Dado que esta está asociada a autoConfig, la manera más fácil aumentar maxconnection en ASP.NET, aplicación consiste en establecer System.Net.ServicePointManager.DefaultConnectionLimit mediante programación en el de Application_Start método en el global.asax archivo.Because this is tied to autoConfig, the easiest way to increase maxconnection in an ASP.NET application is to set System.Net.ServicePointManager.DefaultConnectionLimit programmatically in the from Application_Start method in the global.asax file. Consulte el ejemplo de descarga para obtener un ejemplo.See the sample download for an example.

  • En .NET 4.5, el valor predeterminado de 5000 para MaxConcurrentRequestsPerCPU debiera estar bien.In .NET 4.5, the default of 5000 for MaxConcurrentRequestsPerCPU should be fine.

ColaboradoresContributors