ASP.NET MVC의 비동기 컨트롤러 : 실제 장점 / 어떻게 달성 했습니까?


12

ASP.NET MVC ( http://visualstudiomagazine.com/articles/2013/07/23/async-actions-in-aspnet-mvc-4.aspx )의 비동기 컨트롤러 방법에 대한 기사를 작성 중이며 생각합니다. 요점을 놓칠 수 있습니다.

내가 쓴이 방법을 고려하십시오.이 기사의 예와 매우 유사합니다.

[HttpGet]
[AsyncTimeout(8000)]
[HandleError(ExceptionType = typeof(TimeoutException), View = "TimedOut")]
public async Task<ActionResult> Index(CancellationToken cancellationToken)
{
    WidgetPageViewModel model = new WidgetPageViewModel()
    {
        toAdd = new Widget()
    };
    model.all = await _repo.GetAllAsync(cancellationToken);
    return View(model);
}

내가 이해하는 것처럼, 이것은 런타임에 일이 전개되는 방법입니다.

  1. 들어오는 HTTP 요청에 대해 ASP.NET 스레드가 작성됩니다.

  2. 이 스레드는 (필요한 예비 작업을 수행했을 것입니다) 위의 Index () 메서드를 입력합니다.

  3. 실행은 "await"키워드에 도달하고 다른 스레드에서 데이터 수집 프로세스를 시작합니다.

  4. 원래 "ASP.NET"스레드는 Task 클래스의 인스턴스를 반환 값으로 사용하여 처리기 메서드를 호출 한 코드로 반환됩니다.

  5. 핸들러 메소드를 호출 한 인프라 코드는 실제 ActionResult 객체를 사용해야하는 지점 (예 : 페이지 렌더링)에 도달 할 때까지 원래 "ASP.NET"스레드에서 계속 작동합니다.

  6. 그런 다음 호출자는 Task.Result 멤버를 사용하여이 개체에 액세스합니다.이 멤버 (예 : "ASP.NET"스레드)는 위의 3 단계에서 암시 적으로 생성 된 스레드를 기다립니다.

나는 trifling으로 인식하는 두 가지를 제외하고는 await / async가없는 동일한 것과 비교하여 이것이 성취하는 것을 보지 못했습니다.

  • await에 의해 생성 된 호출자 스레드와 작업자 스레드는 일정 기간 (위의 # 5의 "까지"부분) 동안 병렬로 작동 할 수 있습니다. 제 직감은 시간이 꽤 짧다는 것입니다. 인프라가 컨트롤러 메소드를 호출 할 때 일반적으로 컨트롤러 호출의 실제 ActionResult가 필요하다면 더 많은 것을 수행 할 수 있다고 생각합니다.

  • 장기 실행 비동기 컨트롤러 작업의 시간 초과 및 취소와 관련된 유용한 새 인프라가 있습니다.

비동기 컨트롤러 메서드를 추가하는 목적은 이러한 ASP.NET 작업자 스레드를 해제하여 실제로 HTTP 요청에 응답하는 것입니다. 이 스레드는 유한 한 리소스입니다. 불행히도, 기사에서 제안한 패턴이 실제로 이러한 스레드를 보존하는 방법을 알지 못합니다. 그리고 그렇게하고 어떻게 든 비 ASP.NET 스레드로 요청을 처리하는 부담을 덜어 주더라도 어떻게하면됩니까? 일반적으로 스레드와는 다른 HTTP 요청을 처리 할 수있는 스레드가 있습니까?


Execution will reach the "await" keyword and kick off a data acquisition process on another thread-반드시 그런 것은 아닙니다. async다른 스레드가 필요하지 않습니다 ... 계속입니다. 동일한 스레드에서
Robert Harvey


"실행은 await 키워드에 도달하고 다른 스레드에서 데이터 수집 프로세스를 시작합니다." 당신은 이것을 거꾸로했습니다 : 기다릴 때가 돌아옵니다. GetAllAsync ()의 결과를 변수에 저장하고 대신 기다렸다가 더 명확한 지 확인하십시오.
Esben Skov Pedersen

답변:


9

작업 병렬 라이브러리 (TPL)를 사용하지 않는 ASP.Net은 스레드 풀의 스레드 수에 의해 동시에 처리 할 수있는 요청 수가 제한됩니다. TPL을 사용하는 ASP.Net은 요청을 처리하는 머신의 CPU / 메모리 / IO에 의해 제한됩니다.

작업 병렬 라이브러리 (TPL)는 생각한 것처럼 스레드를 소비하지 않습니다. 작업은 스레드가 아니며 일부 계산 단위를 감싸는 래퍼입니다. 작업 스케줄러는 사용 중이 아닌 스레드에서 각 작업을 실행합니다. 런타임에 작업을 기다리는 것은 스레드를 차단하지 않으며 나중에 실행 상태를 유지하기 위해 실행 상태를 지정 해제합니다.

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


ASP.NET 스레드는 언제 풀로 반환됩니까? "대기"키워드가 검색되면?
user1172763

async / await + TPL을 사용하면 컴파일러가 코드를 작업 스케줄러에서 실행하는 독립적 인 계산 단위로 나눌 수 있습니다. 작업 스케줄러에 더 이상 실행할 수있는 작업이없고 스레드가 주어진 작업을 마치면 스레드가 개념적으로 풀로 반환됩니다.
mortalapeman

이것은 개념 적으로 정확하고 아마도 유용한 해답입니다.하지만 실의 민첩성 때문에 현실이 조금 더 복잡 합니다.
John Wu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.