C # 5 Async / Await-* 동시 *입니까?
저는 C # 5의 새로운 비동기 관련 사항을 고려하고 있는데, 한 가지 특별한 질문이 나왔습니다.
나는 await
키워드가 연속 전달 을 구현하는 깔끔한 컴파일러 트릭 / 구문 설탕 이라는 것을 이해합니다. 여기서 메서드의 나머지 부분은 Task
개체 로 분할 되고 순서대로 실행되도록 대기하지만 제어는 호출 메서드로 반환됩니다.
내 문제는 현재 이것이 모두 단일 스레드에 있다고 들었습니다. 이것은이 비동기 작업이 실제로 연속 코드를 Task
객체 로 변환 한 다음 Application.DoEvents()
각 작업이 완료된 후 다음 작업을 시작하기 전에 호출 하는 방법 일 뿐이라는 것을 의미합니까 ?
아니면 내가 뭔가를 놓치고 있습니까? (질문의이 부분은 수사적입니다-나는 내가 뭔가를 놓치고 있다는 것을 완전히 알고 있습니다 :))
그것은이다 동시에 많은 뛰어난 asychronous 작업은 언제든지 진행이 될 수 있다는 의미에서. 다중 스레드 일 수도 있고 아닐 수도 있습니다 .
기본적으로 await
는 계속을 "현재 실행 컨텍스트"로 다시 예약합니다. "현재 실행 콘텍스트"로 정의 SynchronizationContext.Current
가 비없는 경우 null
, 또는 TaskScheduler.Current
더있을 경우 SynchronizationContext
.
매개 변수 를 호출 ConfigureAwait
하고 전달 하여이 기본 동작을 재정의 할 수 있습니다 . 이 경우 연속은 해당 실행 컨텍스트로 다시 예약되지 않습니다. 이것은 일반적으로 스레드 풀 스레드에서 실행된다는 것을 의미합니다.false
continueOnCapturedContext
라이브러리 코드를 작성하지 않는 한 기본 동작은 정확히 원하는 것입니다. WinForms, WPF 및 Silverlight (즉, 모든 UI 프레임 워크)는를 제공 SynchronizationContext
하므로 연속이 UI 스레드에서 실행되고 UI 개체에 안전하게 액세스 할 수 있습니다. ASP.NET은 또한 SynchronizationContext
올바른 요청 컨텍스트에서 연속이 실행되도록하는를 제공합니다.
다른 스레드 (스레드 풀 스레드 Thread
, 및 포함 BackgroundWorker
)는 SynchronizationContext
. 따라서 기본적으로 콘솔 앱 및 Win32 서비스에는 전혀 없습니다 SynchronizationContext
. 이 상황에서 연속은 스레드 풀 스레드에서 실행됩니다. 사용하여 콘솔 응용 프로그램 데모 이유입니다 await
/ async
호출을 포함 Console.ReadLine
/ ReadKey
또는 차단 할 Wait
A의를 Task
.
.이 필요하다면 내 Nito.AsyncEx 라이브러리 에서 SynchronizationContext
사용할 수 있습니다 . 그것은 기본적으로 그냥 제공 A를 호환 "메인 루프"를 . 콘솔 앱 및 단위 테스트에 유용하다고 생각합니다 (VS2012에는 이제 단위 테스트에 대한 기본 지원이 있음 ).AsyncContext
async
SynchronizationContext
async Task
에 대한 자세한 내용은 SynchronizationContext
참조 내 2월 MSDN 문서를 .
아무 DoEvents
때나 또는 이와 동등한 호출 이 없습니다 . 오히려 제어 흐름 이 끝까지 반환 되고 계속 (나머지 함수)이 나중에 실행되도록 예약됩니다. 이것은 DoEvents
사용 했을 때와 같은 재진입 문제를 일으키지 않기 때문에 훨씬 더 깨끗한 솔루션 입니다.
async / await의 전체 아이디어는 연속 전달을 훌륭하게 수행하고 작업에 새 스레드를 할당하지 않는다는 것입니다. 새 스레드에서 연속 이 발생할 수 있으며 동일한 스레드에서 계속 될 수 있습니다 .
async / await의 실제 "고기"(비동기) 부분은 일반적으로 개별적으로 수행되며 호출자와의 통신은 TaskCompletionSource를 통해 수행됩니다. 여기에 쓰여진대로 http://blogs.msdn.com/b/pfxteam/archive/2009/06/02/9685804.aspx
TaskCompletionSource 유형은 이름으로 언급되는 두 가지 관련 목적을 제공합니다. 두 가지 목적은 작업을 생성하기위한 소스이고 해당 작업을 완료하기위한 소스입니다. 본질적으로 TaskCompletionSource는 Task 및 완료에 대한 생산자 역할을합니다.
예는 매우 명확합니다.
public static Task<T> RunAsync<T>(Func<T> function)
{
if (function == null) throw new ArgumentNullException(“function”);
var tcs = new TaskCompletionSource<T>();
ThreadPool.QueueUserWorkItem(_ =>
{
try
{
T result = function();
tcs.SetResult(result);
}
catch(Exception exc) { tcs.SetException(exc); }
});
return tcs.Task;
}
를 통해 기다릴 수 TaskCompletionSource
있는 Task
개체에 액세스 할 수 있지만 다중 스레딩을 만든 async / await 키워드를 통하지는 않습니다.
많은 "느린"함수가 async / await 구문으로 변환 될 때 많이 사용할 필요가 없습니다 TaskCompletionSource
. 그들은 그것을 내부적으로 사용할 것입니다 (그러나 결국 어딘가에 TaskCompletionSource
비동기 결과를 가져야합니다)
내가 설명하고 싶은 방식은 "await"키워드가 단순히 작업이 완료 될 때까지 기다리지 만 기다리는 동안 호출 스레드에 실행을 양보한다는 것입니다. 그런 다음 Task의 결과를 반환하고 Task가 완료되면 "await"키워드 뒤의 문에서 계속됩니다.
내가 알아 차린 일부 사람들은 Task가 호출 스레드와 동일한 스레드에서 실행된다고 생각하는 것 같습니다. 이것은 올바르지 않으며 호출을 기다리는 메서드 내에서 Windows.Forms GUI 요소를 변경하여 증명할 수 있습니다. 그러나 가능한 경우 호출 스레드에서 연속이 실행됩니다.
Task가 완료 될 때 콜백 델리게이트 나 이벤트 핸들러가 필요하지 않은 깔끔한 방법입니다.
참조 URL : https://stackoverflow.com/questions/7663101/c-sharp-5-async-await-is-it-concurrent
'your programing' 카테고리의 다른 글
JDK8 및 JDK10에서 삼항 연산자의 동작 차이 (0) | 2020.12.25 |
---|---|
Team Foundation Server 2010에 솔루션을 추가 할 때 표시되는 경고 (0) | 2020.12.25 |
ADB를 통해 데이터 삭제 / 초기화 (0) | 2020.12.25 |
시계열 패턴 인식 (0) | 2020.12.25 |
HTML을 인쇄 할 때 페이지에 페이지 번호 인쇄 (0) | 2020.12.25 |