ASP.NET MVC에서 비동기 작업을 사용하는 데 약간의 문제가 있습니다. 언제 내 앱의 성능을 개선합니까? 하지 ?
- ASP.NET MVC의 모든 곳에서 비동기 작업을 사용하는 것이 좋습니까?
- 대기 가능한 방법과 관련하여 (EF / NHibernate / other ORM을 통해) 데이터베이스를 쿼리 할 때 async / await 키워드를 사용해야합니까?
- 하나의 단일 조치 메소드 에서 await 키워드를 사용하여 데이터베이스를 비동기 적으로 쿼리 할 수있는 횟수는 몇 번 입니까?
답변
비동기 조치 메소드는 조치가 여러 개의 독립적 인 장기 실행 조작을 수행해야 할 때 유용합니다.
AsyncController 클래스의 일반적인 용도는 오래 실행되는 웹 서비스 호출입니다.
데이터베이스 호출이 비동기식이어야합니까?
IIS 스레드 풀은 종종 데이터베이스 서버보다 더 많은 동시 차단 요청을 처리 할 수 있습니다. 데이터베이스가 병목 상태 인 경우 비동기 호출은 데이터베이스 응답 속도를 높이 지 않습니다. 제한 메커니즘이 없으면 비동기 호출을 사용하여 더 많은 작업을 압도적 데이터베이스 서버로 효율적으로 디스패치하면 데이터베이스에 대한 부담이 더 커집니다. DB에 병목 현상이 발생하면 비동기 호출이 마법의 총알이 아닙니다.
@PanagiotisKanavos 의견에서 파생되었습니다.
또한 비동기는 병렬을 의미하지 않습니다. 비동기 실행은 복잡한 스레드 나 성능 비용없이 소중한 스레드 풀 스레드가 외부 리소스를 차단하지 않도록합니다. 이는 동일한 IIS 시스템이 더 많은 동시 요청을 처리 할 수 있다는 것을 의미합니다.
또한 차단 호출은 CPU 집약적 스핀 웨이트로 시작해야합니다. 스트레스 시간 동안 통화를 차단하면 지연이 지연되고 앱 풀이 재활용됩니다. 비동기 호출은 단순히 이것을 피하십시오
답변
당신은 내 찾을 수 있습니다 도움이 주제에 대한 MSDN 문서를 ; 이 기사에서는 ASP.NET에서 사용 하는 방법 뿐만 아니라 ASP.NET에서 언제 사용 해야하는지 설명하는 많은 공간을 차지했습니다 .async
async
ASP.NET MVC에서 비동기 작업을 사용하는 데 약간의 문제가 있습니다. 앱 성능을 향상시킬 때와 그렇지 않을 때
먼저 async
/ await
가 스레드 를 해제하는 것임을 이해하십시오 . GUI 응용 프로그램에서는 주로 GUI 스레드를 해제 하여 사용자 경험을 향상시키는 것입니다. 서버 응용 프로그램 (ASP.NET MVC 포함)에서 주로 요청 스레드를 해제하는 것입니다. 서버가 확장 할 수 있도록 입니다.
특히, 그것은 하지 않습니다 :
- 개별 요청을 더 빨리 완료하십시오. 실제로, 그들은 완만하게 (완전히 조금씩) 완만하게 될 것이다.
- 를 누르면 발신자 / 브라우저로 돌아갑니다
await
.await
브라우저가 아닌 ASP.NET 스레드 풀에만 “수율”이됩니다.
첫 번째 질문은 ASP.NET MVC의 모든 곳에서 비동기 작업을 사용하는 것이 좋습니까?
I / O를 수행하는 모든 곳에서 사용하는 것이 좋습니다. 반드시 그런 것은 아닙니다 도움 (아래 참조).
그러나 CPU 바운드 방법에는 사용하지 않습니다 . 때때로 DEVS은의 혜택을받을 수 있다고 생각 async
바로 호출하여Task.Run
는 컨트롤러를 하며 이는 끔찍한 아이디어입니다. 이 코드는 다른 스레드를 사용하여 요청 스레드를 해제하므로 아무런 이점이 없습니다 (실제로 추가 스레드 스위치의 페널티를 받고 있습니다)!
데이터베이스를 쿼리 할 때 (EF / NHibernate / other ORM을 통해) async / await 키워드를 사용해야합니까?
사용 가능한 대기 가능한 방법을 사용할 수 있습니다. 현재 대부분의 주요 플레이어는을 지원 async
하지만 그렇지 않은 플레이어 도 있습니다. 귀하의 ORM이를 지원하지 않는 경우 async
포장하지 마십시오Task.Run
또는 이와 유사한 것을 (위 참조).
내가 ” 사용할 수있다 “고 말했음을 주목하십시오 . 단일 데이터베이스 백엔드로 ASP.NET MVC에 대해 이야기하고 있다면 확장 성 이점을 얻지 못할 것입니다 async
. IIS는 단일 SQL Server 인스턴스 (또는 다른 클래식 RDBMS)보다 훨씬 많은 동시 요청을 처리 할 수 있기 때문입니다. 그러나 백엔드는 더 현대적인 경우 – SQL Server 클러스터, 푸른 SQL, NoSQL의 등 -과 백엔드 확장 할 수 있습니다, 그리고 확장 성 병목 현상, IIS입니다 다음 당신이에서 확장 성 혜택을받을 수 있습니다 async
.
세 번째 질문-하나의 단일 조치 메소드에서 데이터베이스를 비동기식으로 쿼리하기 위해 대기 키워드를 몇 번 사용할 수 있습니까?
당신이 원하는만큼. 그러나 많은 ORM에는 연결 당 하나의 작업 규칙이 있습니다. 특히 EF는 DbContext 당 단일 작업 만 허용합니다. 작업이 동기식인지 비동기식인지에 관계없이 마찬가지입니다.
또한 백엔드의 확장 성을 다시 염두에 두십시오. 단일 SQL Server 인스턴스를 사용 중이고 IIS가 이미 SQLServer를 전체 용량으로 유지할 수있는 경우 SQLServer에 대한 압력을 두 배로 늘리거나 세 배로 늘려도 전혀 도움이되지 않습니다.
답변
ASP.NET MVC의 모든 곳에서 비동기 작업을 사용하는 것이 좋습니까?
프로그램에서 평소와 같이, 그것은 의존한다 . 특정 경로를 따라갈 때 항상 상충 관계가 있습니다.
async-await
서비스에 대한 동시 요청을 받고 잘 확장 할 수있는 곳에서 빛납니다 . 어떻게 async-await
수평 확장에 도움을? 네트워크 호출이나 데이터베이스 히트와 같은 비동기 IO 호출을 동기식 으로 호출하면 실행을 담당하는 현재 스레드가 요청이 완료되기를 기다리는 동안 차단됩니다. 사용할 때async-await
, 당신은 IO 호출이 완료되면, 당신의 방법이 off 상태에서 실행을 계속 확인하게하는 당신을위한 상태 머신을 생성하는 프레임 워크를 가능하게한다.
주목해야 할 것은이 상태 머신에는 미묘한 오버 헤드가 있다는 것입니다. 메소드를 비동기 적으로 만든다고해서 더 빨리 실행되는 것은 아니며 , 이는 많은 사람들이 이해하고 이해하는 데 중요한 요소입니다.
사용할 때 고려해야 할 또 다른 사항 async-await
은 비동기식 이라는 사실입니다 . 즉, 비동기식이 전체 통화 스택에 침투하는 것을 볼 수 있습니다. 즉, 동기식 API를 노출하려는 경우 비동기 및 동기화 가 잘 혼합되지 않기 때문에 일정량의 코드를 복제하는 경우가 종종 있습니다.
데이터베이스를 쿼리 할 때 (EF / NHibernate / other ORM을 통해) async / await 키워드를 사용해야합니까?
비동기 IO 호출을 사용하는 경로를 아래로 async-await
선택하면 점점 더 현대적인 데이터베이스 공급자가 TAP (Task Asynchronous Pattern)를 구현하는 비동기 메서드를 노출하므로 좋습니다.
ONE 단일 조치 메소드에서 await 키워드를 사용하여 데이터베이스를 비동기 적으로 쿼리 할 수있는 횟수는 몇 번입니까?
데이터베이스 제공자가 지정한 규칙을 따르는 한 원하는만큼. 비동기 호출의 양에는 제한이 없습니다. 서로 독립적이며 동시에 수행 할 수있는 쿼리가있는 경우 각각에 대해 새 작업을 수행 await Task.WhenAll
하고 둘 다 완료 될 때까지 사용할 수 있습니다.
답변
내 5 센트 :
async/await
DB 또는 외부 서비스 웹 서비스와 같은 IO 작업을 수행하는 경우에만 사용하십시오 .- 항상 DB에 대한 비동기 호출을 선호하십시오.
- DB를 쿼리 할 때마다
추신 : 포인트 1의 경우는 예외이지만 비동기 내부를 잘 이해해야합니다.
추가적인 이점으로, 필요한 경우 몇 개의 IO 호출을 병렬로 수행 할 수 있습니다.
Task task1 = FooAsync(); // launch it, but don't wait for result
Task task2 = BarAsync(); // launch bar; now both foo and bar are running
await Task.WhenAll(task1, task2); // this is better in regard to exception handling
// use task1.Result, task2.Result
답변
async
작업은 DB 또는 일부 네트워크 바운드 호출에 대한 일부 I / O 작업을 수행하거나 방금 호출 한 DB 또는 네트워크 바운드 호출에서 응답을 받기 전에 요청을 처리하는 스레드가 중단되는 경우에 가장 유용합니다. 함께 사용하는 것이 가장 좋으며 응용 프로그램의 응답 성을 향상시킵니다 (DB 또는 이와 같은 다른 작업을 기다리는 동안 ASP 입력 / 출력 스레드가 중단되기 때문에). 모든 응용 프로그램에서 DB에 대한 많은 호출이 필요할 때마다 항상 훌륭한 방법으로 감싸고 await
키워드로 호출했습니다 .
답변
아시다시피 MVC는 비동기 컨트롤러를 지원하므로이를 활용해야합니다. 컨트롤러가 긴 작업을 수행하는 경우 (디스크 기반 I / O 또는 다른 원격 서비스에 대한 네트워크 호출 일 수 있음) 요청이 동기 방식으로 처리되면 IIS 스레드는 항상 사용 중입니다. 결과적으로 스레드는 긴 작업이 완료되기를 기다리고 있습니다. 처음 요청 된 작업이 진행되는 동안 다른 요청을 처리하여 더 잘 활용할 수 있습니다. 이는 더 많은 동시 요청을 처리하는 데 도움이됩니다. 웹 서비스는 확장 성이 뛰어나며 C10k 문제에 쉽게 부딪치지 않습니다 . db 쿼리에 async / await를 사용하는 것이 좋습니다. 그리고 당신은 당신이 생각하는만큼 여러 번 사용할 수 있습니다.
훌륭한 조언을 위해 여기 를 살펴보십시오 .
답변
내 경험은 오늘날 많은 개발자들이 async/await
들이 컨트롤러의 기본값으로 .
내 제안은 당신이 그것을 도울 것이라는 것을 알고있을 때만 사용하는 것입니다. 입니다.
그 이유는 Stephen Cleary 와 다른 사람들이 이미 언급했듯이 성능 문제를 해결하지 않고 도입 할 수 있으며 특정 시나리오에서만 도움이 될 것입니다.
- 트래픽이 많은 컨트롤러
- 확장 가능한 백엔드