ChatGPT解决这个技术问题 Extra ChatGPT

What is the advantage of using async with MVC5?

What is the difference between:

public ActionResult Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        IdentityResult result = IdentityManager.Authentication.CheckPasswordAndSignIn(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
        if (result.Success)
        {
            return Redirect("~/home");
        }
        else
        {
            AddErrors(result);
        }
    }
    return View(model);
}

and:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        IdentityResult result = await IdentityManager.Authentication.CheckPasswordAndSignInAsync(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
        if (result.Success)
        {
            return Redirect("~/home");
        }
        else
        {
            AddErrors(result);
        }
    }
    return View(model);
}

I see that the MVC code now has async but what is the difference. Does one give much better performance than the other? Is it easier to debug problems with one than the other? Should I make changes to other controllers for my application to add Async ?

In the vast majority of situations there's no serious benefit for using async in MVC, however there are many negatives
@ChrisMarisic - One of the most serious: you can't use ReaderWriterLock or any of the other synchronization primitives (except for Semaphore).

D
Darin Dimitrov

The async actions are useful only when you are performing I/O bound operations such as remote server calls. The benefit of the async call is that during the I/O operation, no ASP.NET worker thread is being used. So here's how the first example works:

When a request hits the action, ASP.NET takes a thread from the thread pool and starts executing it. The IdentityManager.Authentication.CheckPasswordAndSignIn method is invoked. This is a blocking call -> during the entire call the worker thread is being jeopardized.

And here's how the second call works:

When a request hits the action, ASP.NET takes a thread from the thread pool and starts executing it. The IdentityManager.Authentication.CheckPasswordAndSignInAsync is called which returns immediately. An I/O Completion Port is registered and the ASP.NET worker thread is released to the thread pool. Later when the operation completes, the I/O Completion port is signaled, another thread is drawn from the thread pool to finish returning the view.

As you can see in the second case ASP.NET worker threads are used only for a short period of time. This means that there are more threads available in the pool for serving other requests.

So to conclude, use async actions only when you have a true async API inside. If you make a blocking call inside an async action, you are killing the whole benefit of it.


How about context synchronization. Won't this be such an overhead that you do not want to use async actions at all? "The overhead of an async method which actually executes asynchronously depends entirely on whether it needs to switch threads using SynchronizationContext.Post. If it does, the overhead is dominated by the thread switch it performs as it resumes. That means that the current SynchronizationContext makes a big difference." (Async in C# 5.0, 2012, Alex Davies)
@Darin Why is it so important to release the main thread? Are thread limited?
@Omtechguy a better solution is to move non ASP.NET requests to a CDN. A simple CDN is merely using subdomain and separate app pool for physical files like your javascript and images. Alternatively you could use NgineX / Lighttpd / Apache for files, or you could use a third party service such as Akamai (king for CDN but most expensive)
I'm still confused. When the CheckPasswordAndSignInAsync is called, ASP.NET takes another thread from the thread pool and starts executing it, doesn't it? If it doesn't, where is checking password procedure executed in?
G
Gaurang Dhandhukiya

Normally, a single HTTP request would be handled by a single thread, completely removing that thread from the pool until a response is returned. With the TPL, you are not bound by this constraint. Any request that come in starts a continuation with each unit of computation required to calculate a response able to execute on any thread in the pool. With this model, you can handle many more concurrent requests than with standard ASP.Net.

If it is some new task that will be spawned, or not, and if it should be awaited or not. Always think about those 70 ms, which is approx. the max. time that any method call should take. If its longer, then your UI will most probably not feel very responsiveness.


M
Muhammad Essa

In web applications that sees a large number of concurrent requests at start-up or has a bursty load (where concurrency increases suddenly), making these web service calls asynchronous will increase the responsiveness of your application. An asynchronous request takes the same amount of time to process as a synchronous request. For example, if a request makes a web service call that requires two seconds to complete, the request takes two seconds whether it is performed synchronously or asynchronously. However, during an asynchronous call, a thread is not blocked from responding to other requests while it waits for the first request to complete. Therefore, asynchronous requests prevent request queuing and thread pool growth when there are many concurrent requests that invoke long-running operations.


If your aspnet application largely consists of calls to other web servers, you're largely behaving as a 'gateway' / 'proxy' and async is useful for that purpose.