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

Преамбула

Мы реализуем сайт 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() можно было бы так же легко поместить в обработчик событий первого запроса. Я только что показал это здесь, чтобы облегчить чтение.

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

Спасибо!


person rejj    schedule 07.09.2011    source источник
comment
Будет ли OtherActionAsync(e.Result) вызываться асинхронно в этом примере? Не будет ли он вызываться синхронно, когда WebClient завершит загрузку строки?   -  person JimmyP    schedule 07.09.2011
comment
Он будет включать еще один вызов .DownloadStringAsync(), который будет иметь собственный обработчик событий DownloadStringCompleted.   -  person rejj    schedule 07.09.2011
comment
Хм, хорошо, я все еще пытаюсь понять, где вы находитесь в гонке, извините. Пока значение OutstandingOperations увеличивается и уменьшается правильно, все значения должны быть доступны в DoStuffCompleted.   -  person JimmyP    schedule 07.09.2011
comment
Я не уверен, что обработчики событий гарантированно будут выполняться в том же потоке или нет, и нужно ли им вызывать AsyncManager.Sync() или нет, чтобы убедиться, что они работают с одними и теми же параметрами .Parameters (и теми же .OutstandingOperations)   -  person rejj    schedule 07.09.2011
comment
Из вашего примера кода неясно, что делает OtherActionAsync. Вы снова увеличиваете незавершенные операции, когда инициируете другой запрос? ASP.NET вызывает метод ActionCompleted, как только ожидающие асинхронные операции становятся равными 0.   -  person Charles Prakash Dasari    schedule 07.09.2011


Ответы (1)


Получается ответ "Нет".

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

person rejj    schedule 07.01.2012