1

在 ASP.NET CORE 2.0 中,我有这种行为:我从浏览器发送两个 AJAX 请求,第一个请求发送到一个操作(action1,这是一个异步操作),第二个请求发送到另一个操作(action2)。当服务器正在处理第一个请求时,第二个请求排队,然后当第一个请求命中“等待”指令进入动作 1 时,动作 2 立即开始处理第二个请求并且第一个请求进入队列。这是预期的行为,但是如果我在 ASP.NET 4.6 中尝试这个,我会出现这种行为:当第一个请求达到“等待”指令时,第二个请求保持排队,必须等到第一个动作完成整个处理,为第二个动作接收第二个请求。

这是我的服务器端代码

  [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 中则不行。提前致谢。

4

1 回答 1

4

await和关键字的async行为相同。但是这些关键字的行为取决于 SynchronizationContext。不同的是:ASP.NET Core 没有同步上下文

在所有情况下,都await将控制权返回给调用者,并将“延续”(一种指向 之后的代码部分的委托await)发布到SynchronizationContext.Current. 在 ASP.NET(框架)中,这意味着将一次拾取一个延续,从不并行;在 .NET Core 中,它们可以并行执行。

这意味着某些行为会有所不同。例如,在 .NET 框架中,您可以轻松地自己死锁,但许多相同的事情在 ASP.NET 核心中不会死锁,因为主“线程”没有争用(实际上,线程可以切换,因为线程敏捷性,但本质上它是单线程的)。另一方面,.NET 框架中的“线程安全”代码可能会导致 .NET 核心中的并发问题。顺便说一下,SynchronizationContext 在控制台和 WinForms 应用程序中也不同。

在使用 async 和 await 时了解 SynchronizationContext 非常重要,这将取决于代码的运行方式和运行位置。

另请参阅此问题

于 2018-04-13T17:21:14.537 回答