IT Share you

TPL과 비동기 / 대기 (스레드 처리)의 차이점

shareyou 2020. 12. 1. 20:00
반응형

TPL과 비동기 / 대기 (스레드 처리)의 차이점


스레드 생성 과 관련하여 TPL과 async/ 의 차이점을 이해하려고 노력합니다 await.

TPL ( TaskFactory.StartNew)은 ThreadPool.QueueUserWorkItem스레드 풀의 스레드에서 작업을 대기열에 넣는 것과 비슷하게 작동 한다고 생각합니다 . 물론 TaskCreationOptions.LongRunning새 스레드를 만드는 사용하지 않는 한 그렇습니다.

나는 생각했다 async/이 await때문에 본질적으로 유사하게 작동합니다 :

TPL :

Factory.StartNew( () => DoSomeAsyncWork() )
.ContinueWith( 
    (antecedent) => {
        DoSomeWorkAfter(); 
    },TaskScheduler.FromCurrentSynchronizationContext());

Async/ Await:

await DoSomeAsyncWork();  
DoSomeWorkAfter();

동일합니다. 같은 내가 읽어 봤는데 바로는 것 같습니다 async/ await전용 "때때로"새 스레드를 생성합니다. 그러면 언제 새 스레드를 생성하고 언제 새 스레드를 생성하지 않습니까? IO 완료 포트를 다룬다면 새 스레드를 만들 필요가 없다는 것을 알 수 있지만 그렇지 않으면 그렇게해야한다고 생각합니다. 나는 FromCurrentSynchronizationContext항상 나의 이해가 약간 모호하다고 생각합니다. 저는 항상 본질적으로 UI 스레드라고 생각했습니다.


TPL (TaskFactory.Startnew)은 스레드 풀의 스레드에서 작업을 대기열에 추가한다는 점에서 ThreadPool.QueueUserWorkItem과 유사하게 작동한다고 생각합니다.

거의 .

내가 읽은 내용에서 비동기 / 대기 "때때로"새 스레드를 만드는 것처럼 보입니다.

실제로는 그렇지 않습니다. 멀티 스레딩을 원하면 직접 구현해야합니다. Task.Run약칭 인 새로운 방법이 있으며 Task.Factory.StartNew아마도 스레드 풀에서 작업을 시작하는 가장 일반적인 방법 일 것입니다.

IO 완료 포트를 다루고 있다면 새 스레드를 만들 필요가 없다는 것을 알 수 있지만 그렇지 않으면 필요하다고 생각합니다.

빙고. 따라서 같은 메서드 Stream.ReadAsync는 실제로 TaskIOCP ( StreamIOCP가있는 경우) 주위 래퍼를 만듭니다 .

비 I / O, 비 CPU "작업"을 생성 할 수도 있습니다. 간단한 예는 Task.Delay일정 기간 후에 완료되는 작업을 반환하는입니다.

async/ 에 대한 멋진 점은 await스레드 풀 (예 :)에 일부 작업을 대기열에 넣고 (예 :), Task.RunI / O 바운드 작업 (예 :), Stream.ReadAsync다른 작업 (예 :)을 수행 Task.Delay할 수 있다는 것입니다. 모든 작업! 기다릴 수도 있고 Task.WhenAll.

반환하는 모든 메서드는 편집 Task할 수 있습니다 . 메서드 await일 필요는 없습니다 async. 따라서 Task.DelayI / O 바운드 작업 TaskCompletionSource은 작업을 생성하고 완료하는 데 사용 됩니다. 스레드 풀에서 수행되는 유일한 작업은 이벤트가 발생할 때 실제 작업 완료 (시간 초과, I / O 완료 등)입니다.

FromCurrentSynchronizationContext에 대한 이해가 항상 약간 모호한 것 같습니다. 저는 항상 본질적으로 UI 스레드라고 생각했습니다.

대한 기사썼습니다 SynchronizationContext. 대부분의 경우 SynchronizationContext.Current:

  • 현재 스레드가 UI 스레드 인 경우 UI 컨텍스트입니다.
  • 현재 스레드가 ASP.NET 요청을 처리하는 경우 ASP.NET 요청 컨텍스트입니다.
  • 그렇지 않으면 스레드 풀 컨텍스트입니다.

모든 스레드 자체 설정할 SynchronizationContext 있으므로 위의 규칙에 대한 예외가 있습니다.

기본 Taskawaiter는 null이 아닌 경우async 현재 메서드 의 나머지를 예약합니다 . 그렇지 않으면 현재에 간다 . 이것은 오늘날 그다지 중요하지 않지만 가까운 장래에 중요한 구별이 될 것입니다.SynchronizationContext TaskScheduler

나는 내 블로그에 내 자신의 async/ await소개썼고 Stephen Toub는 최근에 훌륭한 async/ awaitFAQ를 게시했습니다 .

"동시성"대 "멀티 스레딩"에 대해서는 이 관련 SO 질문을 참조하십시오 . async다중 스레드 일 수도 있고 아닐 수도있는 동시성을 활성화 한다고 말하고 싶습니다 . 사용 await Task.WhenAll하거나 await Task.WhenAny동시 처리를 수행 하기 쉽고 명시 적으로 스레드 풀 (예 : Task.Run또는 ConfigureAwait(false))을 사용하지 않는 한 동시에 여러 개의 동시 작업을 진행할 수 있습니다 (예 : 여러 I / O 또는 기타 유형 Delay). 스레드가 필요하지 않습니다. 저는 이러한 종류의 시나리오에서 "단일 스레드 동시성"이라는 용어를 사용하지만 ASP.NET 호스트에서는 실제로 " 제로 스레드 동시성"으로 끝날 수 있습니다 . 꽤 달콤합니다.


async / await는 기본적으로 ContinueWith메서드를 단순화합니다 ( Continuation Passing Style의 연속 )

동시성을 도입하지 않습니다. 여전히 직접 수행해야합니다 (또는 프레임 워크 메서드의 비동기 버전을 사용합니다.).

따라서 C # 5 버전은 다음과 같습니다.

await Task.Run( () => DoSomeAsyncWork() );
DoSomeWorkAfter();

참고 URL : https://stackoverflow.com/questions/10285159/difference-between-the-tpl-async-await-thread-handling

반응형