작업입니다.ASP.NET MVC 웹 응용 프로그램에서 잘못된 것으로 간주되는 관행을 실행하시겠습니까?
배경
우리는 현재 ASP.NET MVC 5, Angular에 의존하는 웹 애플리케이션을 개발하고 있습니다.JS 1.4, Web API 2 및 Entity Framework 6.확장성의 이유로 웹 애플리케이션의 비중은 비동기/대기 패턴에 의존합니다.도메인에는 몇 초(10초 미만)의 시간이 걸릴 수 있는 몇 가지 CPU 집약적인 계산이 필요합니다.이전에는 일부 팀 구성원이 작업을 사용했습니다.계산 속도를 높이기 위해 실행합니다.ASP.NET MVC 또는 Web API 컨트롤러 내에서 추가 스레드를 시작하는 것은 잘못된 관행으로 간주되므로(스레드는 IIS에서 알 수 없으므로 AppDomain Recycle => Stephen Cleary의 블로그 게시물 참조) ConfigureAwit(거짓)를 사용했습니다.
예
public async Task CalculateAsync(double param1, double param2)
{
// CalculateSync is synchronous and cpu-intensive (<10s)
await Task.Run(() => this.CalculateSync(param1, param2))).ConfigureAwait(false);
}
문의사항
- 작업을 사용할 때 성능상의 이점이 있습니까?CPU 바인딩 작업을 위해 비동기 웹 API 컨트롤러에서 실행하시겠습니까?
- ConfigureAwait(거짓)은 정말로 추가 스레드 생성을 방지합니까?
작업을 사용할 때 성능상의 이점이 있습니까?CPU 바인딩 작업을 위해 비동기 웹 API 컨트롤러에서 실행하시겠습니까?
0. 없습니다.사실, 당신은 새로운 스레드를 생성함으로써 성능을 저해하고 있습니다.웹 애플리케이션의 맥락에서 스레드를 생성하는 것은 "백그라운드"에서 실행하는 것과 같지 않습니다.이는 웹 요청의 특성으로 인해 발생합니다.수신 요청이 있을 때 요청을 처리하기 위해 풀에서 스레드를 가져옵니다.비동기를 사용하면 스레드가 대기 상태(즉, 유휴 상태)에 있는 경우에만 요청이 끝나기 전에 스레드를 반환할 수 있습니다.작업할 스레드를 생성하면 기본 스레드가 효과적으로 유휴 상태가 되어 풀로 반환되지만 활성 스레드가 있습니다.원본 스레드를 풀로 되돌리면 해당 시점에서는 아무 작업도 수행되지 않습니다.그런 다음 새 스레드가 작업을 마치면 풀에서 주 스레드를 다시 요청하고 마지막으로 응답을 반환해야 합니다.모든 작업이 완료될 때까지 응답을 반환할 수 없으므로 스레드 1개를 사용하든 100개를 사용하든 비동기 또는 동기화를 사용하든 모든 작업이 완료될 때까지 응답을 반환할 수 없습니다.따라서 스레드를 추가로 사용하면 오버헤드만 추가됩니다.
ConfigureAwait(거짓)은 정말로 추가 스레드 생성을 방지합니까?
아니요, 더 정확히 말하면, 그것은 그것에 관한 것이 아닙니다. ConfigureAwait
는 최적화 힌트일 뿐이며 스레드 점프 간에 원래 컨텍스트가 유지되는지 여부만 결정합니다.요약하자면, 스레드 생성과 관련이 없으며, 적어도 ASP.NET 응용 프로그램의 맥락에서는 성능에 미치는 영향이 어느 쪽이든 미미합니다.
사용 시 성능상의 이점이 있습니까?
Task.Run
CPU 바인딩 작업을 위한 비동기 웹 API 컨트롤러에서?
아니요. 그리고 CPU 바인딩 여부는 중요하지 않습니다.
Task.Run
작업을 a로 오프로드ThreadPool
실.웹 API 요청이 이미 사용 중입니다.ThreadPool
스레드를 사용하므로 이유 없이 다른 스레드로 오프로드하여 확장성을 제한할 수 있습니다.
이는 UI 스레드가 특수 단일 스레드인 UI 앱에서 유용합니다.
ConfigureAwait(거짓)은 정말로 추가 스레드 생성을 방지합니까?
어떤 식으로든 스레드 생성에는 영향을 주지 않습니다.캡처된 파일에서 다시 시작할지 여부를 구성하는 것이 전부입니다.SynchronizationContext
그렇지 않으면.
작업을 사용할 때 성능상의 이점이 있습니까?CPU 바인딩 작업을 위해 비동기 웹 API 컨트롤러에서 실행하시겠습니까?
실제로 무슨 일이 일어나는지 생각해 보세요.Task.Run()
스레드 풀에 작업을 생성합니다.await
연산자가 스레드를 해제합니다(스택 아래의 모든 메서드도 대기 중인 것 같습니다).이제 스레드가 풀로 돌아왔는데 동일한 작업을 선택할 수 있습니다!이 시나리오에서는 분명히 성능 향상이 없습니다.사실은 실적에 타격이 있습니다.그러나 스레드가 다른 작업을 선택하는 경우(아마도 그렇게 될 것입니다), 다른 스레드를 선택해야 합니다.CalculateSync()
작업을 수행하고 전자 장치가 멈춘 위치에서 계속합니다.원래 스레드가 실행되도록 하는 것이 더 이치에 맞았을 것입니다.CalculateSync()
처음에는 관련된 작업이 없으며 다른 스레드에 다른 대기 중인 작업이 포함되도록 합니다.
ConfigureAwait(거짓)은 정말로 추가 스레드 생성을 방지합니까?
천만에요.그것은 단지 계속이 발신자의 맥락에서 실행되어서는 안 된다는 것을 지적합니다.
당신이 고려해야 할 것이 하나 더 있습니다.당신이 당신의 api가 CPU 집약적인 작업을 하고 있다고 말했듯, 비동기/대기는 다른 스레드에서 프로세스를 실행하고 다른 요청을 위해 당신의 앱 풀을 확보하는 데 도움을 줍니다.비동기/대기를 올바르게 사용할 경우 웹 API가 초당 더 많은 요청을 처리할 수 있음을 의미합니다.
당신의 경우는 다음과 같습니다.this.CalculateSync(param1, param2)
비동기 메서드가 아니므로 비동기식으로 호출하려면 작업을 사용해야 합니다. 뛰어요.
제거할 것을 권장합니다..ConfigureAwait(false)
이렇게 하면 실제로 성능이 저하되기 때문입니다.
언급URL : https://stackoverflow.com/questions/33764366/is-task-run-considered-bad-practice-in-an-asp-net-mvc-web-application
'source' 카테고리의 다른 글
루비에서 문자열을 URL 인코딩하는 방법 (0) | 2023.07.06 |
---|---|
Visual Studio 2013에서 TypeScript를 사용하는 방법 (0) | 2023.07.06 |
확인하지 못했습니다. com.google.파이어베이스:파이어베이스-코어:11.2.0 (0) | 2023.07.06 |
해시를 저장하기 위해 어떤 종류의 데이터 유형을 사용해야 합니까? (0) | 2023.07.06 |
vimdiff를 사용하여 모든 'gitdiff' 보기 (0) | 2023.07.06 |