성능 테스트는 스레드 풀 연속으로 Begin 또는 Async API를 사용하는 것과 비교하여 전용 동기 데이터 읽기 스레드 사용시 거의 2 배의 성능 이점을 나타 냈습니다. (행 수천만이 많은 초에서 적재되기 때문에, 우리는이 경우에 성능을 선호합니다.)
연장의 편리한 토큰 전달을위한 방법
public static SqlDataReader ExecuteReader(this SqlCommand command, CommandBehavior commandBehavior, CancellationToken cancel)
{
try
{
using (cancel.Register(command.Cancel))
return command.ExecuteReader(commandBehavior);
}
catch (SqlException)
{
cancel.ThrowIfCancellationRequested();
throw;
}
}
내가 리플렉터 컴파일 일부 동굴 탐험을했다. 시작 및 비동기 버전은 모두 매우 절약 적이지만 완전히 TPL 비동기를 기반으로합니다. 그렇기 때문에 둘 다에서 연속에 대한 스레드 풀 디스 패칭이 있습니다.
이 확장 메서드는 스레드 오버 헤드가 없습니다. 토큰 소스에서 Cancel
을 호출하는 스레드는 command.Cancel
을 호출하여 즉시 데이터 스레드에 SqlException
을 발생시킵니다.
당신은 동기 코드를 고수하고 싶습니다. 왜'ExecuteReader (...) '를'ExecuteReaderAsync (token, ...).'로 대체하지 않았습니까? 'Task.Run'으로 랩핑하지 않아도됩니다. – Noseratio
@Noseratio Duh, UI 스레드에서 교착 상태가 발생하는 데 익숙하지만 백그라운드 스레드의 경우 ExecuteReaderAsync (...). 결과가 아름답게 작동합니다. 잠깐, 블록스럽지 않고 스레드 풀 스레드를 사용하여 연속 작업을 처리합니까? 내 확장 메서드는 모든 스레드에서 한 스레드에 머무르는 이점이 있다고 생각합니다. – jnm2
예, ExecuteReaderAsync (...). 결과는 호출 된 스레드를 차단합니다. 그러나 장면 뒤에 비동기 IO를 사용할 수 있으므로 반드시 스레드를 차단하는 것은 아닙니다. (확실하지는 않지만 논리적입니다.) 어쨌든, 당신이 앱의 확장성에 관심이 있다면'async/await'을 사용하고 스레드를 중복해서 차단하지 마십시오. – Noseratio