Использование асинхронных методов в ASP.NET MVC 4Using Asynchronous Methods in ASP.NET MVC 4

по Рик Андерсон (by Rick Anderson

В этом учебнике вы узнаете об основах создания асинхронного веб-приложения ASP.NET MVC с помощью Visual Studio Express 2012 для Web, которое является бесплатной версией Microsoft Visual Studio.This tutorial will teach you the basics of building an asynchronous ASP.NET MVC Web application using Visual Studio Express 2012 for Web, which is a free version of Microsoft Visual Studio. Также можно использовать Visual Studio 2012.You can also use Visual Studio 2012.

Полный пример для этого руководства приведен на сайте GitHub https://github.com/RickAndMSFT/Async-ASP.NET/A complete sample is provided for this tutorial on github https://github.com/RickAndMSFT/Async-ASP.NET/

Класс контроллера ASP.NET MVC 4 в сочетании с .NET 4,5 позволяет создавать асинхронные методы действия, возвращающие объект типа Task<ActionResult>.The ASP.NET MVC 4 Controller class in combination .NET 4.5 enables you to write asynchronous action methods that return an object of type Task<ActionResult>. В .NET Framework 4 появилась концепция асинхронного программирования, называемая задачей , а ASP.NET MVC 4 поддерживает задачу.The .NET Framework 4 introduced an asynchronous programming concept referred to as a Task and ASP.NET MVC 4 supports Task. Задачи представлены типом задачи и связанными типами в пространстве имен System. Threading. Tasks .Tasks are represented by the Task type and related types in the System.Threading.Tasks namespace. .NET Framework 4,5 построена на этой асинхронной поддержке с помощью ключевых слов await и Async , которые делают работу с объектами задач гораздо менее сложными, чем предыдущие асинхронные подходы.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. Ключевое слово await — это сокращенная синтаксическая форма, указывающая, что фрагмент кода должен асинхронно ожидать какой-либо другой фрагмент кода.The await keyword is syntactical shorthand for indicating that a piece of code should asynchronously wait on some other piece of code. Ключевое слово Async представляет указание, которое можно использовать для пометки методов как асинхронных методов, основанных на задачах.The async keyword represents a hint that you can use to mark methods as task-based asynchronous methods. Сочетание await, Asyncи объекта Task значительно упрощает написание асинхронного кода в .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. Новая модель для асинхронных методов называется асинхронной моделью на основе задач (TAP).The new model for asynchronous methods is called the Task-based Asynchronous Pattern (TAP). В этом учебнике предполагается, что вы знакомы с асинхронной программой с помощью ключевых слов await и Async и пространства имен Task .This tutorial assumes you have some familiarity with asynchronous programing using await and async keywords and the Task namespace.

Дополнительные сведения о ключевых словах с использованием await и Async и пространстве имен задачи см. в следующих статьях.For more information on the using await and async keywords and the Task namespace, see the following references.

Обработка запросов пулом потоковHow Requests Are Processed by the Thread Pool

На веб-сервере .NET Framework поддерживает пул потоков, используемых для обслуживания запросов ASP.NET.On the web server, the .NET Framework maintains a pool of threads that are used to service ASP.NET requests. При получении запроса, для его обработки из этого пула выделяется поток.When a request arrives, a thread from the pool is dispatched to process that request. Если запрос обрабатывается синхронно, поток, обрабатывающий запрос, занят во время обработки запроса, и этот поток не может обслуживать другой запрос.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.

Это может не быть проблемой, так как пул потоков можно сделать достаточно большим для размещения множества занятых потоков.This might not be a problem, because the thread pool can be made large enough to accommodate many busy threads. Однако количество потоков в пуле потоков ограничено (максимальное значение по умолчанию для .NET 4,5 — 5 000).However, the number of threads in the thread pool is limited (the default maximum for .NET 4.5 is 5,000). В больших приложениях с высоким параллелизмом долго выполняющихся запросов все доступные потоки могут быть заняты.In large applications with high concurrency of long-running requests, all available threads might be busy. Такая ситуация называется нехваткой потоков.This condition is known as thread starvation. При достижении этого условия веб-сервер помещает запросы в очередь.When this condition is reached, the web server queues requests. Если очередь запросов заполнена, веб-сервер отклоняет запросы с состоянием HTTP 503 (сервер слишком занят).If the request queue becomes full, the web server rejects requests with an HTTP 503 status (Server Too Busy). Пул потоков CLR имеет ограничения на новые внедрения потоков.The CLR thread pool has limitations on new thread injections. Если параллелизм — это пакетная обработка (то есть веб-сайт может получить большое количество запросов), а все доступные потоки запросов заняты из-за внутренних вызовов с высокой задержкой, ограниченная скорость внедрения потоков может привести к плохому реагированию приложения.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. Кроме того, каждый новый поток, добавляемый в пул потоков, имеет накладные расходы (например, 1 МБ стековой памяти).Additionally, each new thread added to the thread pool has overhead (such as 1 MB of stack memory). Веб-приложение, использующее синхронные методы для обработки вызовов с высокой задержкой, когда пул потоков увеличился до версии .NET 4,5 по умолчанию (5), 000 потоков потребляет примерно 5 ГБ памяти, чем приложение может обрабатывать те же запросы с помощью асинхронные методы и только 50 потоков.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. При выполнении асинхронной работы вы не всегда используете поток.When you're doing asynchronous work, you're not always using a thread. Например, при выполнении асинхронного запроса веб-службы ASP.NET не будет использовать потоки между асинхронным вызовом метода и 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. Использование пула потоков для запросов на обслуживание с высокой задержкой может привести к увеличению объема памяти и низкому использованию аппаратного обеспечения сервера.Using the thread pool to service requests with high latency can lead to a large memory footprint and poor utilization of the server hardware.

Обработка асинхронных запросовProcessing Asynchronous Requests

В веб-приложении, которое видит большое количество одновременных запросов при запуске или имеет более интенсивную нагрузку (при внезапном увеличении параллелизма), вызов веб-службы асинхронно увеличивает скорость реагирования приложения.In a web app that sees a large number of concurrent requests at start-up or has a bursty load (where concurrency increases suddenly), making web service calls asynchronous increases the responsiveness of the app. Асинхронный запрос обрабатывается такое же количество времени, что и синхронный запрос.An asynchronous request takes the same amount of time to process as a synchronous request. Если запрос выполняет вызов веб-службы, для которого требуется две секунды, запрос занимает две секунды независимо от того, выполняется ли оно синхронно или асинхронно.If a request makes a web service call that requires two seconds to complete, the request takes two seconds whether it's performed synchronously or asynchronously. Однако во время асинхронного вызова поток не блокирует реагирование на другие запросы, пока он ожидает завершения первого запроса.However during an asynchronous call, a thread isn't blocked from responding to other requests while it waits for the first request to complete. Поэтому асинхронные запросы предотвращают увеличение очереди запросов и роста пула потоков при наличии большого количества параллельных запросов, вызывающих длительные операции.Therefore, asynchronous requests prevent request queuing and thread pool growth when there are many concurrent requests that invoke long-running operations.

Выбор синхронных или асинхронных методов действияChoosing Synchronous or Asynchronous Action Methods

В этом подразделе перечислены рекомендации, когда использовать синхронные или асинхронные методы действия.This section lists guidelines for when to use synchronous or asynchronous action methods. Это только рекомендации. Изучите каждое приложение по отдельности, чтобы определить, помогают ли асинхронные методы обеспечить производительность.These are just guidelines; examine each application individually to determine whether asynchronous methods help with performance.

Как правило, используйте синхронные методы для следующих условий:In general, use synchronous methods for the following conditions:

  • Операции являются простыми и кратковременными.The operations are simple or short-running.
  • Простота имеет большое значение, чем эффективность.Simplicity is more important than efficiency.
  • Операции в основном являются операциями ЦП, а не операциями, в которых широко используется диск или сетевые ресурсы.The operations are primarily CPU operations instead of operations that involve extensive disk or network overhead. Использование асинхронных методов действия в операциях, которые связаны с ЦП, не дает преимущества и приводит к дополнительному расходу ресурсов.Using asynchronous action methods on CPU-bound operations provides no benefits and results in more overhead.

Как правило, используйте асинхронные методы для следующих условий:In general, use asynchronous methods for the following conditions:

  • Вы вызываете службы, которые могут использоваться асинхронными методами, и вы используете .NET 4,5 или более поздней версии.You're calling services that can be consumed through asynchronous methods, and you're using .NET 4.5 or higher.
  • Операции связаны с использованием сети или ввода-вывода, а не с ЦП.The operations are network-bound or I/O-bound instead of CPU-bound.
  • Параллелизм имеет большее значение, чем простота кода.Parallelism is more important than simplicity of code.
  • Необходимо предоставить механизм, который позволяет пользователям отменить длительные по времени запросы.You want to provide a mechanism that lets users cancel a long-running request.
  • Если преимущество переключения потоков превышает затраты на переключение контекста.When the benefit of switching threads outweighs the cost of the context switch. Как правило, метод следует делать асинхронным, если синхронный метод ожидает поток запроса ASP.NET, не выполняя никаких действий.In general, you should make a method asynchronous if the synchronous method waits on the ASP.NET request thread while doing no work. Делая вызов асинхронным, поток запроса ASP.NET не зависает, пока ожидает завершения запроса веб-службы.By making the call asynchronous, the ASP.NET request thread is not stalled doing no work while it waits for the web service request to complete.
  • Тестирование показывает, что блокирующие операции являются узким местом в производительности сайта и что IIS может обслуживать больше запросов с помощью асинхронных методов для этих блокирующих вызовов.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.

В примере показано, как эффективно использовать асинхронные методы действия.The downloadable sample shows how to use asynchronous action methods effectively. Представленный образец предназначен для простой демонстрации асинхронного программирования в ASP.NET MVC 4 с использованием .NET 4,5.The sample provided was designed to provide a simple demonstration of asynchronous programming in ASP.NET MVC 4 using .NET 4.5. Образец не предназначен для использования в качестве эталонной архитектуры для асинхронного программирования в ASP.NET MVC.The sample is not intended to be a reference architecture for asynchronous programming in ASP.NET MVC. Пример программы вызывает веб-API ASP.NET методы, которые в свою очередь вызывают Task. Delay для имитации длительно выполняемых вызовов веб-служб.The sample program calls ASP.NET Web API methods which in turn call Task.Delay to simulate long-running web service calls. Большинство рабочих приложений не будут показывать такие очевидные преимущества при использовании асинхронных методов действий.Most production applications will not show such obvious benefits to using asynchronous action methods.

Несколько приложений требуют, чтобы все методы действия были асинхронными.Few applications require all action methods to be asynchronous. Часто преобразование нескольких синхронных методов действия в асинхронные методы обеспечивают наилучший прирост эффективности для выполнения требуемого объема работ.Often, converting a few synchronous action methods to asynchronous methods provides the best efficiency increase for the amount of work required.

Пример приложенияThe Sample Application

Вы можете скачать пример приложения из https://github.com/RickAndMSFT/Async-ASP.NET/ на сайте GitHub .You can download the sample application from https://github.com/RickAndMSFT/Async-ASP.NET/ on the GitHub site. Репозиторий состоит из трех проектов:The repository consists of three projects:

  • Mvc4Async: проект ASP.NET MVC 4, содержащий код, используемый в этом руководстве.Mvc4Async: The ASP.NET MVC 4 project that contains the code used in this tutorial. Он выполняет вызовы веб-API в службу вебапипгв .It makes Web API calls to the WebAPIpgw service.
  • Вебапипгв: проект веб-API ASP.NET MVC 4, который реализует контроллеры Products, Gizmos and Widgets.WebAPIpgw: The ASP.NET MVC 4 Web API project that implements the Products, Gizmos and Widgets controllers. Он предоставляет данные для проекта вебаппасинк и проекта Mvc4Async .It provides the data for the WebAppAsync project and the Mvc4Async project.
  • Вебаппасинк: проект веб-форм ASP.NET, используемый в другом учебнике.WebAppAsync: The ASP.NET Web Forms project used in another tutorial.

Синхронный метод действия приспособленийThe Gizmos Synchronous Action Method

В следующем коде показан Gizmos синхронный метод действия, используемый для отображения списка приспособлений.The following code shows the Gizmos synchronous action method that is used to display a list of gizmos. (В этой статье гизмо — вымышленное механическое устройство.)(For this article, a gizmo is a fictional mechanical device.)

public ActionResult Gizmos()
{
    ViewBag.SyncOrAsync = "Synchronous";
    var gizmoService = new GizmoService();
    return View("Gizmos", gizmoService.GetGizmos());
}

В следующем коде показан метод GetGizmos службы гизмо.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)
            );
        }
    }
}

Метод GizmoService GetGizmos передает универсальный код ресурса (URI) веб-API ASP.NET службе HTTP, которая возвращает список данных приспособлений.The GizmoService GetGizmos method passes a URI to an ASP.NET Web API HTTP service which returns a list of gizmos data. Проект вебапипгв содержит реализацию gizmos, widget и контроллеров product веб-API.The WebAPIpgw project contains the implementation of the Web API gizmos, widget and product controllers.
На следующем рисунке показано представление приспособлений из примера проекта.The following image shows the gizmos view from the sample project.

Приспособлений

Создание асинхронного метода действия приспособленийCreating an Asynchronous Gizmos Action Method

В примере используются новые ключевые слова Async и await (доступные в .NET 4,5 и Visual Studio 2012), позволяющие компилятору отвечать за поддержание сложных преобразований, необходимых для асинхронного программирования.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. Компилятор позволяет писать код с помощью C#синхронных конструкций потока управления, и компилятор автоматически применяет преобразования, необходимые для использования обратных вызовов, чтобы избежать блокировки потоков.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.

В следующем коде показан синхронный метод Gizmos и асинхронный метод GizmosAsync.The following code shows the Gizmos synchronous method and the GizmosAsync asynchronous method. Если браузер поддерживает элемент HTML 5 <mark>, вы увидите, что изменения в GizmosAsync выделены желтым цветом.If your browser supports the HTML 5 <mark> element, you'll see the changes in GizmosAsync in yellow highlight.

public ActionResult Gizmos()
{
    ViewBag.SyncOrAsync = "Synchronous";
    var gizmoService = new GizmoService();
    return View("Gizmos", gizmoService.GetGizmos());
}
public async Task<ActionResult> GizmosAsync()
{
    ViewBag.SyncOrAsync = "Asynchronous";
    var gizmoService = new GizmoService();
    return View("Gizmos", await gizmoService.GetGizmosAsync());
}

Для обеспечения асинхронности GizmosAsync были применены следующие изменения.The following changes were applied to allow the GizmosAsync to be asynchronous.

  • Метод помечается ключевым словом Async , которое указывает компилятору создавать обратные вызовы для частей тела и автоматически создавать Task<ActionResult>, которые возвращаются.The 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<ActionResult> that is returned.
  • "Async" был добавлен к имени метода."Async" was appended to the method name. Добавление "Async" не является обязательным, но является соглашением при написании асинхронных методов.Appending "Async" is not required but is the convention when writing asynchronous methods.
  • Тип возвращаемого значения изменен с ActionResult на Task<ActionResult>.The return type was changed from ActionResult to Task<ActionResult>. Тип возвращаемого значения Task<ActionResult> представляет текущую работу и предоставляет вызывающие методы метода с помощью обработчика, который ожидает завершения асинхронной операции.The return type of Task<ActionResult> represents ongoing work and provides callers of the method with a handle through which to wait for the asynchronous operation's completion. В этом случае вызывающей стороной является веб-служба.In this case, the caller is the web service. Task<ActionResult> представляет текущую работу с результатом ActionResult.Task<ActionResult> represents ongoing work with a result of ActionResult.
  • Ключевое слово await было применено к вызову веб-службы.The await keyword was applied to the web service call.
  • Вызван API асинхронной веб-службы (GetGizmosAsync).The asynchronous web service API was called (GetGizmosAsync).

В теле метода GetGizmosAsyncа другой асинхронный метод, вызывается GetGizmosAsync.Inside of the GetGizmosAsync method body another asynchronous method, GetGizmosAsync is called. GetGizmosAsync немедленно возвращает Task<List<Gizmo>>, который в конечном итоге завершится, когда данные станут доступны.GetGizmosAsync immediately returns a Task<List<Gizmo>> that will eventually complete when the data is available. Так как вы не хотите делать что-то еще, пока не гизмо данные, код ожидает задачу (с помощью ключевого слова await ).Because you don't want to do anything else until you have the gizmo data, the code awaits the task (using the await keyword). Ключевое слово await можно использовать только в методах, снабженных ключевым словом Async .You can use the await keyword only in methods annotated with the async keyword.

Ключевое слово await не блокирует поток до завершения задачи.The await keyword does not block the thread until the task is complete. Он регистрирует оставшуюся часть метода в качестве обратного вызова задачи и сразу же возвращает.It signs up the rest of the method as a callback on the task, and immediately returns. Когда ожидаемая задача в конечном итоге завершается, она вызывает этот обратный вызов и, таким способом, возобновляет выполнение метода прямо там, где он был отключен.When the awaited task eventually completes, it will invoke that callback and thus resume the execution of the method right where it left off. Дополнительные сведения об использовании ключевых слов await и Async и пространства имен задачи см. в статье асинхронные ссылки.For more information on using the await and async keywords and the Task namespace, see the async references.

В следующем коде приведены методы GetGizmos и GetGizmosAsync.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 (HttpClient httpClient = new HttpClient())
    {
        var response = await httpClient.GetAsync(uri);
        return (await response.Content.ReadAsAsync<List<Gizmo>>());
    }
}

Асинхронные изменения похожи на те, которые были сделаны в гизмосасинк выше.The asynchronous changes are similar to those made to the GizmosAsync above.

  • Сигнатура метода была помечена ключевым словом Async , тип возвращаемого значения был изменен на Task<List<Gizmo>>, а Async был добавлен к имени метода.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.
  • Вместо класса WebClient используется асинхронный класс HttpClient .The asynchronous HttpClient class is used instead of the WebClient class.
  • Ключевое слово await было применено к асинхронным методам HttpClient .The await keyword was applied to the HttpClient asynchronous methods.

На следующем рисунке показано асинхронное представление гизмо.The following image shows the asynchronous gizmo view.

async

Представление данных приспособлений в браузерах идентично представлению, созданному синхронным вызовом.The browsers presentation of the gizmos data is identical to the view created by the synchronous call. Единственное отличие заключается в том, что асинхронная версия может быть более производительной при высоких нагрузках.The only difference is the asynchronous version may be more performant under heavy loads.

Параллельное выполнение нескольких операцийPerforming Multiple Operations in Parallel

Асинхронные методы действия имеют значительное преимущество по сравнению с синхронными методами, когда действие должно выполнять несколько независимых операций.Asynchronous action methods have a significant advantage over synchronous methods when an action must perform several independent operations. В предоставленном примере синхронный метод PWG(для продуктов, мини-приложений и приспособлений) отображает результаты трех вызовов веб-службы для получения списка продуктов, мини-приложений и приспособлений.In the sample provided, the synchronous method PWG(for Products, Widgets and Gizmos) displays the results of three web service calls to get a list of products, widgets, and gizmos. Проект веб-API ASP.NET , предоставляющий эти службы, использует Task. Delay для имитации задержки или медленных сетевых вызовов.The ASP.NET Web API project that provides these services uses Task.Delay to simulate latency or slow network calls. Если задержка задана равным 500 миллисекундам, асинхронный метод PWGasync выполняет несколько более 500 миллисекунд, пока синхронная PWGная версия занимает свыше 1 500 миллисекунд.When the delay is set to 500 milliseconds, the asynchronous PWGasync method takes a little over 500 milliseconds to complete while the synchronous PWG version takes over 1,500 milliseconds. Синхронный PWG метод показан в следующем коде.The synchronous PWG method is shown in the following code.

public ActionResult PWG()
{
    ViewBag.SyncType = "Synchronous";
    var widgetService = new WidgetService();
    var prodService = new ProductService();
    var gizmoService = new GizmoService();

    var pwgVM = new ProdGizWidgetVM(
        widgetService.GetWidgets(),
        prodService.GetProducts(),
        gizmoService.GetGizmos()
       );

    return View("PWG", pwgVM);
}

Асинхронный метод PWGasync показан в следующем коде.The asynchronous PWGasync method is shown in the following code.

public async Task<ActionResult> PWGasync()
{
    ViewBag.SyncType = "Asynchronous";
    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
       );

    return View("PWG", pwgVM);
}

На следующем рисунке показано представление, возвращаемое методом пвгасинк .The following image shows the view returned from the PWGasync method.

пвгасинк

Использование токена отменыUsing a Cancellation Token

Асинхронные методы действия, возвращающие Task<ActionResult>, являются отменяемыми, то есть принимают параметр CancellationToken , если он предоставляется с атрибутом AsyncTimeout .Asynchronous action methods returning Task<ActionResult>are cancelable, that is they take a CancellationToken parameter when one is provided with the AsyncTimeout attribute. В следующем коде показан метод GizmosCancelAsync с временем ожидания 150 миллисекунд.The following code shows the GizmosCancelAsync method with a timeout of 150 milliseconds.

[AsyncTimeout(150)]
[HandleError(ExceptionType = typeof(TimeoutException),
                                    View = "TimeoutError")]
public async Task<ActionResult> GizmosCancelAsync(
                       CancellationToken cancellationToken )
{
    ViewBag.SyncOrAsync = "Asynchronous";
    var gizmoService = new GizmoService();
    return View("Gizmos",
        await gizmoService.GetGizmosAsync(cancellationToken));
}

В следующем коде показана перегрузка Жетгизмосасинк, которая принимает параметр CancellationToken .The following code shows the GetGizmosAsync overload, which takes a CancellationToken parameter.

public async Task<List<Gizmo>> GetGizmosAsync(string uri,
    CancellationToken cancelToken = default(CancellationToken))
{
    using (HttpClient httpClient = new HttpClient())
    {
        var response = await httpClient.GetAsync(uri, cancelToken);
        return (await response.Content.ReadAsAsync<List<Gizmo>>());
    }
}

В предоставленном образце приложения выбор демонстрационной ссылки токена отмены вызывает метод GizmosCancelAsync и демонстрирует отмену асинхронного вызова.In the sample application provided, selecting the Cancellation Token Demo link calls the GizmosCancelAsync method and demonstrates the cancellation of the asynchronous call.

Конфигурация сервера для вызовов веб-службы с высоким уровнем параллелизма и высокой задержкойServer Configuration for High Concurrency/High Latency Web Service Calls

Чтобы реализовать преимущества асинхронного веб-приложения, может потребоваться внести некоторые изменения в конфигурацию сервера по умолчанию.To realize the benefits of an asynchronous web application, you might need to make some changes to the default server configuration. При настройке и нагрузочном тестировании асинхронного веб-приложения учитывайте следующее.Keep the following in mind when configuring and stress testing your asynchronous web application.

  • Windows 7, Windows Vista и все клиентские операционные системы Windows имеют максимум 10 одновременных запросов.Windows 7, Windows Vista and all Windows client operating systems have a maximum of 10 concurrent requests. Для просмотра преимуществ асинхронных методов при высокой нагрузке потребуется операционная система Windows Server.You'll need a Windows Server operating system to see the benefits of asynchronous methods under high load.

  • Зарегистрируйте .NET 4,5 со службами IIS из командной строки с повышенными привилегиями:Register .NET 4.5 with IIS from an elevated command prompt:
    %windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis-i%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis -i
    См . раздел ASP.NET IIS Registration Tool (Aspnet_regiis. exe) .See ASP.NET IIS Registration Tool (Aspnet_regiis.exe)

  • Может потребоваться увеличить ограничение очереди http. sys на значение по умолчанию 1 000 до 5 000.You might need to increase the HTTP.sys queue limit from the default value of 1,000 to 5,000. Если значение параметра слишком мало, то можно увидеть запросы отклонения http. sys с состоянием HTTP 503.If the setting is too low, you may see HTTP.sys reject requests with a HTTP 503 status. Чтобы изменить ограничение очереди HTTP. sys, сделайте следующее:To change the HTTP.sys queue limit:

    • Откройте диспетчер IIS и перейдите в область пулы приложений.Open IIS manager and navigate to the Application Pools pane.
    • Щелкните правой кнопкой мыши целевой пул приложений и выберите Дополнительные параметры.Right click on the target application pool and select Advanced Settings.
      дополнительныеadvanced
    • В диалоговом окне Дополнительные параметры измените длину очереди с 1 000 на 5 000.In the Advanced Settings dialog box, change Queue Length from 1,000 to 5,000.
      Длина очереди Queue length

    Обратите внимание, что на приведенных выше изображениях платформа .NET Framework указана как версия 4.0, несмотря на то, что пул приложений использует .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. Чтобы понять это расхождение, см. следующие сведения:To understand this discrepancy, see the following:

  • Если приложение использует веб-службы или System.NET для взаимодействия с серверной частью по протоколу HTTP, может потребоваться увеличить элемент элемент connectionManagement/maxConnection .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. Для приложений ASP.NET это ограничено функцией автонастройки в 12 раз больше, чем количество процессоров.For ASP.NET applications, this is limited by the autoConfig feature to 12 times the number of CPUs. Это означает, что на четырехъядерном уровне можно использовать не более 12 * 4 = 48 одновременных подключений к конечной точке IP.That means that on a quad-proc, you can have at most 12 * 4 = 48 concurrent connections to an IP end point. Поскольку это связано с автоматической конфигурацией, самый простой способ увеличить maxconnection в приложении ASP.NET — установить System .NET. ServicePointManager. DefaultConnectionLimit программно в метод from Application_Start в файле Global. asax .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. Пример см. в примере загрузки.See the sample download for an example.

  • В .NET 4,5 значение по умолчанию 5000 для максконкуррентрекуестсперкпу должно быть точным.In .NET 4.5, the default of 5000 for MaxConcurrentRequestsPerCPU should be fine.