In ASP.NET CORE 2.0 I have this behavior: I send two AJAX requests from the browser, the first request to one action (action1 this is an async action) and the second request to other action (action2). While the server is processing the first request, the second request is queued, then when the first request hits the "await" instruction into the action 1, immediately the action 2 start processing the second request and the first request become queued. And this is the expected behavior, but then If I try this in ASP.NET 4.6 I have this behavior: When the first request hits the "await" instruction, the second request keep queued and have to wait until the first action finish the entire processing, for the second action to receive the second request.
This is my server side code
[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");
}
This Is my 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);
}
What i want to get is a response from the parallel action in each iteration of the loop. This behavior works fine in an ASP.NET 2.0 project but not in ASP.NET 4.6. Thanks In advance.
The
await
andasync
keywords do behave the same. But the behavior of these keywords depends on the SynchronizationContext. And the difference is: ASP.NET Core has no synchronization context.In all cases,
await
returns control to the caller and posts a "continuation" (sort of a delegate pointing at the the portion of code afterawait
) to theSynchronizationContext.Current
. In ASP.NET (framework), this means the continuations will be picked up one at time, never in parallel; in .NET Core, they can execute in parallel.This means certain behaviors will be different. For example, in .NET framework, you can 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, but essentially it's single-threaded). On the other hand, code that is "thread safe" in .NET framework might cause concurrency issues in .NET core. The SynchronizationContext, by the way, is also different in Console and WinForms apps.
It is really really important to understand the SynchronizationContext when using async and await, and it's going to depend on how and where the code is going to run.
See also this question.