Оператор await имеет другое поведение в ASP.NET, чем в ASP.NET CORE?

В ASP.NET CORE 2.0 у меня такое поведение: я отправляю два запроса AJAX из браузера, первый запрос к одному действию (action1 это асинхронное действие) и второй запрос к другому действию (action2). Пока сервер обрабатывает первый запрос, второй запрос ставится в очередь, затем, когда первый запрос попадает в команду 1 "ожидание", действие 2 немедленно начинает обработку второго запроса, и первый запрос становится в очередь. И это ожидаемое поведение, но затем, если я попробую это в ASP.NET 4.6, у меня будет такое поведение: когда первый запрос попадает в инструкцию "await", второй запрос остается в очереди и должен ждать, пока первое действие не завершит все обработка, для второго действия, чтобы получить второй запрос.

Это мой код на стороне сервера

  [HttpPost]
    public async Task<JsonResult> LongRunningAction(HttpPostedFileBase file)
    {
        for (int i = 0; i < 100; i++)
        {                
            await Task.Delay(300);
        }
        return Json("finish");
    }

    [HttpPost]
    public ActionResult ParallelAction()
    {
        return this.Content("result");
    }

Это мой JS:

startParallelRequest();
startLongRunningRequest()

function startLongRunningRequest(){
    $.ajax(
        {
            url: "/mycontroller/LongRunningAction",
            data: null,
            processData: false,
            contentType: false,
            type: "POST",
            success: function () {
                stopParallelAction();
            }
        }
    )
} 

var intervalId;

function startParallelRequest() {
    intervalId = setInterval(
        function () {
            $.ajax(
                {
                    url: "/mycontroller/ParallelAction",
                    data: null,
                    processData: false,
                    contentType: false,
                    type: "POST",
                    success: function () {
                    }
                }
            );
        },
        1000
    );
}

function stopParallelRequest() {
    clearInterval(intervalId);
}

Я хочу получить ответ от параллельного действия в каждой итерации цикла. Такое поведение прекрасно работает в проекте ASP.NET 2.0, но не в ASP.NET 4.6. Заранее спасибо.

1 ответ

Решение

await а также async ключевые слова ведут себя одинаково. Но поведение этих ключевых слов зависит от SynchronizationContext. И разница в том, что ASP.NET Core не имеет контекста синхронизации.

Во всех случаях, await возвращает управление вызывающей стороне и отправляет "продолжение" (своего рода делегат, указывающий на часть кода после await) к SynchronizationContext.Current, В ASP.NET (framework) это означает, что продолжения будут подбираться по одному, а не параллельно; в.NET Core они могут выполняться параллельно.

Это означает, что определенное поведение будет отличаться. Например, в.NET Framework вы можете легко взаимоблокировать себя, но многие из тех же вещей не будут взаимоблокироваться в ядре ASP.NET, потому что нет конкуренции для основного "потока" (на самом деле поток может переключаться из-за проворство, но по сути это однопоточное). С другой стороны, "потокобезопасный" код в.NET Framework может вызвать проблемы параллелизма в ядре.NET. Кстати, SynchronizationContext также отличается в приложениях Console и WinForms.

Действительно очень важно понимать SynchronizationContext при использовании async и await, и это будет зависеть от того, как и где будет выполняться код.

Смотрите также этот вопрос.

Другие вопросы по тегам