await 运算符在 ASP.NET 上的行为与在 ASP.NET CORE 上的行为不同?

The await operator has a different behavior on ASP.NET than on ASP.NET CORE?

在 ASP.NET CORE 2.0 中我有这样的行为: 我从浏览器发送了两个 AJAX 请求,第一个请求是一个动作(action1,这是一个异步动作),第二个请求是另一个动作(action2)。 当服务器处理第一个请求时,第二个请求排队,然后当第一个请求命中 "await" 指令进入动作 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 中无效。 提前致谢。

awaitasync 关键字的行为相同。但是这些关键字的行为取决于 SynchronizationContext。而不同的是:ASP.NET Core has no synchronization context

在所有情况下,await returns 控制调用者并发布一个 "continuation"(某种委托指向 await 之后的代码部分)到 SynchronizationContext.Current。在 ASP.NET (框架)中,这意味着连续将一次被拾取一个,永远不会并行;在 .NET Core 中,它们 可以 并行执行。

这意味着某些行为会有所不同。例如,在 .NET 框架中,您可以 easily deadlock yourself, but many of the same things won't deadlock in ASP.NET core because there is no contention for the main "thread" (in reality, the thread can switch due to threading agility,但本质上它是单线程的)。另一方面,.NET Framework 中的 "thread safe" 代码可能会导致 .NET Core 中的并发问题。顺便说一句,SynchronizationContext 在 Console 和 WinForms 应用程序中也不同。

在使用 async 和 await 时理解 SynchronizationContext 非常重要,这将取决于代码将如何运行以及运行到何处 运行。

另见 this question