비동기 흐름을 통해 1000 개의 요소 목록을 데이터베이스에 기록해야한다고 가정합니다. 비동기 삽입 문을 1000 번 기다리는 것이 더 좋습니까 아니면 Task.Run
문에 캡슐화 된 단일 동기 메서드에 1000 개의 삽입을 모두 래핑하여 한 번만 기다리십니까?많은 사람들이 비동기 메서드를 기다리고 있거나 랩핑 Task.Run을 기다리는 사람이 하나 있습니다.
예를 들어 SqlCommand
에는 모든 방법이 그의 async
버전과 결합되어 있습니다. 이 경우 insert 문이 있으므로 ExecuteNonQuery
또는 ExecuteNonQueryAsync
을 호출 할 수 있습니다.
종종 async/await 가이드 라인에서 비동기 버전을 사용할 수있는 경우이를 사용해야합니다. 다음과 같이 작성한다고 가정 해 보겠습니다.
async Task Save(IEnumerable<Savable> savables)
{
foreach(var savable in savables)
{
//create SqlCommand somehow
var sqlCmd = CreateSqlCommand(savable);
//use asynchronous version
await sqlCmd.ExecuteNonQueryAsync();
}
}
이 코드는 매우 명확합니다. 그러나 대기중인 부분에서 나올 때마다 UI 스레드에서 반환하고 다음 백그라운드 스레드에서 다시 발생하는 등 기다리고 있습니다 (그렇지 않습니까?). UI 슬록이 await
의 계속에 의해 연속적으로 인터럽트되어 다음 foreach
사이클을 실행하고 UI의 일부가 정지되면 사용자가 약간의 지연을 볼 수 있음을 의미합니다. 이런 식으로
async Task Save(IEnumerable<Savable> savables)
{
await Task.Run(() =>
{
foreach(var savable in savables)
{
//create SqlCommand somehow
var sqlCmd = CreateSqlCommand(savable);
//use synchronous version
sqlCmd.ExecuteNonQuery();
}
});
}
, 전체 foreach
는 UI 스레드와 보조 일 사이에 연속 스위치없이, 보조 스레드에서 실행됩니다
는 나는이 같은 더 나은 코드를 작성하는 경우 알고 싶어요. 이것은 UI 스레드가 foreach
(예 : 회 전자 또는 진행률 막대)의 전체 기간 동안보기를 자유롭게 업데이트 할 수 있음을 의미합니다. 즉, 사용자가 지체를 감지하지 않습니다.
맞습니까? 또는 "비동기 도중 내내 무언가를 놓치고 있습니까?"
나는 간단한 의견 기반 답변을 찾고 있지 않다. 그런 경우에는 async/await 지침에 대한 설명을 찾고 최선의 해결 방법을 찾고있다.
편집 : 나는 this question을 읽었지만 동일하지 않습니다
. 질문은 단일 await
을 비동기 방식으로 선택하고 대 Task.Run
을 기다리는 것입니다. 이 질문은 1000 await
및 스레드 간의 연속 전환으로 인한 자원의 오버 헤드로 인한 결과에 대한 것입니다.
가능한 [Task.Run을 사용하여 비동기 메서드를 호출하는 것이 잘못된 것 같습니까?] (http://stackoverflow.com/questions/32606485/calling-an-async-method-using-a-task-run-seems) -wrong) – Liam
당신이 놓치고있는 것은 쓰레드가 극도로 비싸다는 것입니다. 그렇게 할 수 있다면 쓰레드를 만들지 않는 것이 좋습니다. – Aron
'Task.Run' 메소드는 비동기식 anti 패턴 *과 동기화됩니다. Do not do – Liam