2014-06-18 4 views
4

비동기 호출 때문에 aync라는 ASP MVC 호출이 있습니다. 몇 번의 저속 동기화 통화 (예 : db 액세스)가 있음을 확인했습니다. 이 메소드는 진행하기 위해 반환 된 모든 데이터를 사용할 수 있어야합니다.느린 전화를 Task.Run으로 포장해야합니까?

나는 Sync 호출을 Task.Run으로 래핑하고 모든 것을 기다리고 있다고 생각했다.

저속 동기화 호출을 래핑하는 것이 맞습니까? 동기화 통화 만 있다면 어떻게 될까요?

답변

0

작업이 독립적 (다른 작업의 데이터에 의존하지 않음)하고 독립적으로 수행 할 수 있다면 예, 모든 작업을 비동기 적으로 수행하십시오. Entity Framework이고 버전 6이라면 호출 할 Async 메서드를 제공하므로 Task.Run에 래핑 할 필요가 없습니다.

작업이 독립적이 아니어도 실행될 때 작업을 더욱 효율적으로 수행 할 수 있도록 작업을 주문할 수 있습니다.

그러나 Task.Run의 사용 여부는 중요한 차이입니다. Task.Run은 ThreadPool 스레드를 사용합니다. ThreadPool 스레드는 동기식 작업을 수행하면 차단되어 응용 프로그램에서 사용할 수있는 ThreadPool theads 수를 줄입니다. 많은 사용자가 있고 많은 작업을 실행하는 경우 문제가 될 수 있습니다.

Task.Run 대신 async api를 찾아보십시오.

5

동시에 제공 할 것으로 예상되는 클라이언트 요청 수가 실제로 낮은 경우가 아니면 서버 측 코드에서 작업을 병렬 처리하는 데 Task.Run을 사용하지 마십시오. 그렇지 않으면 개별 요청 처리 속도가 빨라지지만 사용자가 많은 경우 웹 응용 프로그램의 확장성에 해를 끼칠 수 있습니다.

+0

async/await를 사용하여 요청을 처리하기 위해 대기하는 대신 현재 스레드를 저장할 수 없습니까? 병렬 작업이 필요한 경우 TPL을 사용해야하지만 TAP을 사용하면 장애가 발생하지 않고 확장성에 도움이됩니다. –

+0

@RyanPeters, 실제로 그렇습니다.하지만 서버 측 컨텍스트에서는 자연스럽게 비동기 API에만 TAP을 사용합니다 (Stephen Cleary의 "Thread Is No Thread"확인 (http://blog.stephencleary.com/2013/11). /there-is-no-thread.html)). 이렇게하면 HTTP 요청의 초기 스레드가 풀로 해제 된 다음 다른 HTTP 요청을 제공 할 수 있습니다. 그러나'Task.Run'을 사용하면 스레드를 해제하지 않습니다. 단일 동기 호출을 래핑하는 것과 관련해서는 전혀 이해가되지 않습니다. 현재 스레드에서 수행 할 수도 있습니다. 병렬로 여러 호출을 래핑하는 것과 마찬가지로 확장 성이 손상됩니다. – Noseratio

+1

확장성에 신경 쓰지 않고 UI 스레드를 응답 성있게 유지하는 클라이언트 측 UI 앱의 경우에는 상황이 다를 수 있습니다. – Noseratio

1

@Noseratio를 시도하고 확장하려면 동기화 작업을 "속도를 높이려면"스레드를 돌리면 대단히 나쁩니다.

중요 사항 기억해야 할 점은 ASP.NET 내부에서 Task.Run을 사용하면 런타임에 수행해야 할 작업을 대기중인 것으로 인식하지 못하기 때문에 IIS가 때때로 응용 프로그램을 재생하려고 시도 할 수 있으므로 매우 위험합니다. 무의식적으로 갑작스럽게 일하라.

.NET Framework 4.5.2를 사용하는 경우 HostingEnvironment.QueueBackgroundWorkItem을 통한 해결 방법이 있습니다. Fire and Forget on ASP.NET에서 자세한 내용을 볼 수 있습니다. 그렇지 않은 경우 맞춤 구현을 위해 Returning Early from ASP.NET Requests을 읽으십시오. 이 두 훌륭한 기사는 모두 @StephanCleary에 있습니다.

+1

저자가 여기 일찍 돌아 오는 것에 대해 이야기하는 것 같지 않습니다. 당신은 화재와 잊어 버림, 또는 비동기 무효화 방법에 대해 이야기하고 있습니다. 이것은 당신이 말하는 문제를 유발할 수 있습니다. 이 경우 작업 결과가 필요하므로 작업자 프로세스가 재활용 될 때까지 기다려야합니다. 그래서 Task.Run을 사용하는 것은 "위험"하지 않습니다. @Noseratio는 확장성에 대해서는별로 좋지 않다고 말합니다. –

+0

그는 이러한 작업을 기다리고 있기 때문에 IIS가 '기다리고 있지만'eveb를 재활용하지 않을 이유가 없습니다. ASP.NET에서 비동기 void 또는 fire 및 forget에 대해 이야기하지 않고 있습니다. –

+1

기본 작업 스레드가 완료되지 않고 대기 중이면 시간이 초과되지 않으면 재활용하지 않을 것입니다. . 화재와 잊어 버림에 대해 이야기하지 않는다면 왜 그 두 기사에 대해 언급 했습니까? –

관련 문제