스레드 생성-Task.Factory.StartNew 대 new Thread ()


102

.Net 4의 새로운 스레딩 및 병렬 라이브러리에 대해 배우고 있습니다.

과거에는 다음과 같이 새 스레드를 만들었습니다 (예제).

DataInThread = new Thread(new ThreadStart(ThreadProcedure));
DataInThread.IsBackground = true;
DataInThread.Start();

이제 할 수 있습니다.

Task t = Task.Factory.StartNew(() =>
{
   ThreadProcedure();
});

차이점이 있다면 무엇입니까?

감사


1
스레드 풀 스케줄러가 작동하는 방식에 대해 조금 걱정할 필요가 있습니다. 그것은 큰 차이를 만들 수 있지만 모든 것은 스레드 내부에서 실제로 수행하는 작업에 달려 있습니다.
Hans Passant 2011 년

답변:


79

큰 차이가 있습니다. 작업은 ThreadPool에서 예약되며 적절한 경우 동기식으로 실행될 수도 있습니다.

오래 실행되는 백그라운드 작업이있는 경우 올바른 작업 옵션을 사용하여이를 지정해야합니다.

더 최적화되어 있으므로 명시 적 스레드 처리보다 Task Parallel Library를 선호해야합니다. 또한 Continuation과 같은 더 많은 기능이 있습니다.


5
아니요. 단지 작업을 시작합니다. 이것은 스레드 풀에 태스크를 추가하거나 동 기적으로 실행할 수 있습니다. TPL은 스레드 / 동시성을 직접 관리에서 당신을 해방하고 (사용하는 코어와 같은) 플랫폼에 가장 적합한 사용에 관한 것입니다
sanosdole

10
항상 다른 스레드를 생성하는 TaskCreationOptions.LongRunning 옵션이 있지만 요점은 왜 다른 스레드가 필요한가요? 병렬로 무언가를하고 싶다면 (Main은 Task가 실행되는 동안 sth.) 최적화 된 라이브러리가 스레드와 같은 시스템 리소스를 활용하여 가장 효율적인 방식으로이를 수행하는 방법을 결정하도록하는 것이 좋습니다.
sanosdole

3
이 msdn 문서에서는 작업을 예약하는 방법을 설명합니다. 장기 실행 및 인라인 (동기 실행)을 다룹니다. msdn.microsoft.com/en-us/library/dd997402.aspx
sanosdole

2
@sming 요점은 새 스레드를 원하지 않는 것이 아니라 UI를 차단하지 않고 동시에 처리하려는 것입니다. ThreadPool은 UI 스레드를 차단하지 않지만 스레드를 생성하여 수동으로 수행 할 수있는 것보다 훨씬 효율적으로 백그라운드 스레드를 관리합니다. 그것이 TPL이 도입하는 마인드 프로세스의 변화입니다. 스레드를 생각하지 말고 동시 작업을 생각하십시오.
sanosdole

4
@sming 죄송합니다, 그 문장이 너무 거칠 었습니다. 작업의 동기 실행을 인라인이라고합니다. UI 스레드에서 스레드 풀 (기본 스케줄러)에 대한 작업을 예약 할 때 작업이 발생하지 않습니다. 앰비언트 스케줄러 ( 'TaskScheduler.Current')가 '.Wait ()'를 호출하는 작업의 스케줄러와 동일한 경우에만 발생합니다. '.Wait ()'가 차단 중이므로 어쨌든 UI를 차단합니다. Short : wait를 호출하지 않고 동 기적으로 실행되지 않습니다.
sanosdole

74

이 태스크는 태스크 API의 모든 장점을 제공합니다.

  • 연속 추가 ( Task.ContinueWith)
  • 여러 작업이 완료되기를 기다리는 중 (모두 또는 일부)
  • 작업에서 오류를 캡처하고 나중에 조사
  • 취소 캡처 (시작할 취소 지정 가능)
  • 잠재적으로 반환 값이 있음
  • C # 5에서 await 사용
  • 스케줄링에 대한 더 나은 제어 (장시간 실행되는 경우, 작업을 생성 할 때 그렇게하여 작업 스케줄러가이를 고려할 수 있도록하십시오)

두 경우 모두 메서드 그룹 변환을 사용하여 코드를 약간 더 간단하게 만들 수 있습니다.

DataInThread = new Thread(ThreadProcedure);
// Or...
Task t = Task.Factory.StartNew(ThreadProcedure);

8
+1. 나는 그것에 Thread비해 매우 낮은 수준 을 추가하고 싶습니다 Task( 자세히 설명 하는 블로그 게시물 이 있습니다). 저는 Grand Rapids DevDay 에서 "실제에서 작업 사용"과 같은 종류의 강연을하고 있습니다. 더 이상 필요가 없기 때문에 "Thread is Dead"라고합니다 Thread(을 구현하지 않는 한 TaskScheduler).
Stephen Cleary

@StephenCleary, Thread백그라운드 스레드로 사용되는 경우 죽었다는 것을 의미한다고 가정 합니까?
썰물

1
@ebb : 아니요, 첫 번째 댓글에 설명 된 더 강력한 입장을 취합니다. 어디에도 없습니다 Thread할 (또는 수 BackgroundWorker더 우아 할 수 없습니다) Task적절하고는 TaskScheduler.
Stephen Cleary 2011 년

1
@StephenCleary, 어떻게 사용하지 않고 전용 스레드를 만들 수 Thread있습니까?
썰물

4
@ebb : "전용 스레드"가 명확하지 않습니다. 당신이 원하는 경우 Task특정 스레드에서 실행 한 후 적절한를 사용 TaskScheduler- 예 AsyncContextThread. 그러나 이것은 일반적으로 필요하지 않습니다. SynchronizationContext, ThreadPool그리고 ConcurrentExclusiveSchedulerPair스케줄러는 대부분의 프로그램에 대한 충분합니다.
Stephen Cleary 2011 년

12

첫 번째 경우에는 단순히 새 스레드를 시작하고 두 번째 경우에는 스레드 풀에 입력합니다.

스레드 풀 작업은 공유 및 재활용 스레드입니다. 새 스레드를 생성해야 할 때마다 몇 밀리 초가 손실되는 것을 방지 할 수 있습니다.

스레드 풀에 들어가는 방법에는 여러 가지가 있습니다.

  • TPL (Task Parallel Library)을 사용하여
  • ThreadPool.QueueUserWorkItem 을 호출하여
  • 대리자에서 BeginInvoke 를 호출 하여
  • BackgroundWorker 를 사용할 때

1

첫 번째 코드 블록은 CLR에게 백그라운드로 실행될 수있는 스레드 (예 : T)를 만들도록 지시합니다 (T를 예약 할 때 스레드 풀 스레드 사용). 간단히 말해서 CLR에게 무언가를 수행 할 스레드를 생성하도록 명시 적으로 요청하고 시작할 스레드에서 Start () 메서드를 호출합니다.

두 번째 코드 블록은 동일하지만 태스크 팩토리 구현에서 StartNew 메서드를 통해 스레드 (백그라운드-다시 스레드 풀에서 실행 됨) 및 시작 스레드를 만드는 책임을 위임 (암시 적으로 전달)합니다.

이것은 주어진 코드 블록 간의 빠른 차이입니다. 그래도 Google을 검색하거나 동료 기여자의 다른 답변을 볼 수있는 세부적인 차이는 거의 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.