ASP.NET MVC2 AsyncController: вызывает ли выполнение нескольких последовательных асинхронных операций возможное состояние гонки? - PullRequest
0 голосов
/ 07 сентября 2011

Преамбула

Мы внедряем сайт MVC2, который должен использовать внешний API через https (боюсь, мы не можем использовать WCF или даже SOAP WebServices старого стиля). Мы используем AsyncController везде, где нам нужно для связи с API, и пока все работает нормально.

В некоторых сценариях нам нужно делать несколько последовательных вызовов API, используя результаты одного шага для выполнения следующего.

Общая схема (упрощенная для демонстрационных целей) пока такова:

public class WhateverController : AsyncController
{
    public void DoStuffAsync(DoStuffModel data)
    {
        AsyncManager.OutstandingOperations.Increment();
        var apiUri = API.getCorrectServiceUri();
        var req = new WebClient();
        req.DownloadStringCompleted += (sender, e) =>
        {
            AsyncManager.Parameters["result"] = e.Result;
            AsyncManager.OutstandingOperations.Decrement();
        };
        req.DownloadStringAsync(apiUri);
    }

    public ActionResult DoStuffCompleted(string result)
    {
        return View(result);
    }
}

У нас есть несколько действий, которые должны выполнять параллельные API-вызовы, и это уже отлично работает; мы просто выполняем несколько запросов и обеспечиваем правильное увеличение AsyncManager.OutstandingOperations.

Сценарий

Для последовательного выполнения нескольких запросов на обслуживание API мы вызываем следующий шаг в обработчике событий для первого запроса DownloadStringCompleted. например,

req.DownloadStringCompleted += (sender, e) =>
{
    AsyncManager.Parameters["step1"] = e.Result;
    OtherActionAsync(e.Result);
    AsyncManager.OutstandingOperations.Decrement();
}

, где OtherActionAsync - это другое действие, определенное в этом же контроллере по той же схеме, что и определенная выше.

Вопрос

Может ли вызов других асинхронных действий из обработчика событий вызвать возможную гонку при доступе к значениям в AsyncManager?

Я попытался просмотреть MSDN, но все комментарии о AsyncManager.Sync() касались шаблона BeginMethod / EndMethod с IAsyncCallback. В этом случае документация предупреждает о возможных условиях гонки.

Нам не нужно на самом деле вызывать другое действие в контроллере, если это не устраивает вас. Код для создания еще одного WebClient и вызова .DownloadStringAsync(), который можно так же легко поместить в обработчик событий первого запроса. Я только что показал это здесь, чтобы его было легче читать.

Надеюсь, это имеет смысл! Если нет, пожалуйста, оставьте комментарий, и я постараюсь уточнить все, что вам нравится.

Спасибо!

1 Ответ

0 голосов
/ 07 января 2012

Оказывается, ответ "Нет".

(для дальнейшего использования, если кто-нибудь столкнется с этим вопросом через поиск)

...