MVC5에서 비동기를 사용하면 어떤 이점이 있습니까?


120

차이점은 무엇입니까?

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);
}

과:

[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);
}

이제 MVC 코드에 비동기가 있지만 차이점은 무엇입니까? 하나가 다른 것보다 훨씬 더 나은 성능을 제공합니까? 다른 것보다 문제를 디버깅하는 것이 더 쉽습니까? 내 응용 프로그램에서 Async를 추가하려면 다른 컨트롤러를 변경해야합니까?


상황의 대부분에서 MVC에서 비동기 사용에 대한 심각한 이익이 없다, 그러나 많은 부정이있다
크리스 Marisic

1
@ChrisMarisic-가장 심각한 문제 중 하나 : ReaderWriterLock 또는 다른 동기화 기본 요소 (Semaphore 제외)를 사용할 수 없습니다.
Quarkly

답변:


170

비동기 작업은 원격 서버 호출과 같은 I / O 바인딩 작업을 수행 할 때만 유용합니다. 비동기 호출의 이점은 I / O 작업 중에 ASP.NET 작업자 스레드가 사용되지 않는다는 것입니다. 첫 번째 예제의 작동 방식은 다음과 같습니다.

  1. 요청이 작업에 도달하면 ASP.NET은 스레드 풀에서 스레드를 가져와 실행을 시작합니다.
  2. IdentityManager.Authentication.CheckPasswordAndSignIn메서드가 호출됩니다. 이것은 차단 호출-> 전체 호출 중에 작업자 스레드가 위험에 처해 있습니다.

두 번째 호출이 작동하는 방식은 다음과 같습니다.

  1. 요청이 작업에 도달하면 ASP.NET은 스레드 풀에서 스레드를 가져와 실행을 시작합니다.
  2. IdentityManager.Authentication.CheckPasswordAndSignInAsync즉시 반환 되는 이 호출됩니다. I / O 완료 포트가 등록되고 ASP.NET 작업자 스레드가 스레드 풀로 해제됩니다.
  3. 나중에 작업이 완료되면 I / O 완료 포트가 신호를 받고 스레드 풀에서 다른 스레드를 가져와 뷰 반환을 완료합니다.

두 번째 경우에서 볼 수 있듯이 ASP.NET 작업자 스레드는 짧은 시간 동안 만 사용됩니다. 이는 다른 요청을 처리하기 위해 풀에 더 많은 스레드를 사용할 수 있음을 의미합니다.

결론적으로, 내부에 진정한 비동기 API가있는 경우에만 비동기 작업을 사용하십시오. 비동기 작업 내에서 차단 호출을 수행하면 모든 이점이 없어집니다.


컨텍스트 동기화는 어떻습니까? 이것은 비동기 작업을 전혀 사용하고 싶지 않을 정도로 오버 헤드가되지 않습니까? "실제로 비동기 적으로 실행되는 비동기 메서드의 오버 헤드는 SynchronizationContext.Post를 사용하여 스레드를 전환해야하는지 여부에 따라 전적으로 달라집니다. 그렇다면 오버 헤드는 재개 할 때 수행하는 스레드 전환에 의해 좌우됩니다. 즉, 현재 SynchronizationContext가 큰 차이. " (비동기 C # 5.0, 2012 년, 알렉스 데이비스)
annemartijn

1
@Darin 메인 스레드를 해제하는 것이 왜 그렇게 중요한가요? 스레드가 제한되어 있습니까?
Omtechguy

1
@Omtechguy 더 나은 솔루션은 비 ASP.NET 요청을 CDN으로 이동하는 것입니다. 간단한 CDN은 자바 스크립트 및 이미지와 같은 실제 파일에 대해 하위 도메인과 별도의 앱 풀을 사용하는 것입니다. 또는 파일에 NgineX / Lighttpd / Apache를 사용하거나 Akamai와 같은 타사 서비스를 사용할 수 있습니다 (CDN의 경우 가장 비싸지 만)
Chris Marisic 2016 년

아직도 혼란 스럽습니다. 가되면 CheckPasswordAndSignInAsync이라고, ASP.NET, 그렇지 않는 스레드 풀에서 또 다른 스레드를 받아 그것을 실행을 시작? 그렇지 않은 경우 어디에서 checking password procedure실행됩니까?
KevinBui

2

일반적으로 단일 HTTP 요청은 단일 스레드에서 처리되며 응답이 반환 될 때까지 풀에서 해당 스레드를 완전히 제거합니다. TPL을 사용하면이 제약에 구속되지 않습니다. 들어오는 모든 요청은 풀의 모든 스레드에서 실행할 수있는 응답을 계산하는 데 필요한 각 계산 단위로 연속을 시작합니다. 이 모델을 사용하면 표준 ASP.Net보다 더 많은 동시 요청을 처리 할 수 ​​있습니다.

생성 될 새로운 작업인지 여부, 대기해야하는지 여부. 항상 약 70ms에 대해 생각하십시오. 최대. 모든 메소드 호출에 걸리는 시간. 그 길이가 길면 UI가 응답 성을 느끼지 못할 것입니다.


0

시작시 많은 수의 동시 요청을 보거나 버스트로드 (동시성이 갑자기 증가하는 경우)가있는 웹 애플리케이션에서 이러한 웹 서비스 호출을 비동기식으로 만들면 애플리케이션의 응답 성이 증가합니다. 비동기 요청은 동기 요청과 처리하는 데 동일한 시간이 걸립니다. 예를 들어 요청이 완료하는 데 2 ​​초가 필요한 웹 서비스 호출을 수행하는 경우 요청이 동기식으로 수행 되든 비동기 적으로 수행 되든 2 초가 걸립니다. 그러나 비동기 호출 중에 스레드는 첫 번째 요청이 완료되기를 기다리는 동안 다른 요청에 대한 응답이 차단되지 않습니다. 따라서 비동기 요청은 장기 실행 작업을 호출하는 동시 요청이 많을 때 요청 대기열 및 스레드 풀 증가를 방지합니다.


aspnet 애플리케이션이 주로 다른 웹 서버에 대한 호출로 구성되어있는 경우 주로 '게이트웨이'/ '프록시'로 작동하고 비동기가 이러한 목적에 유용합니다.
Chris Marisic
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.