Task.Start (), Task.Run () 및 Task.Factory.StartNew () 사용에 대해


143

동일한 작업을 수행하는 TPL 사용에 관한 3 가지 루틴을 보았습니다. 코드는 다음과 같습니다.

public static void Main()
{
    Thread.CurrentThread.Name = "Main";

    // Create a task and supply a user delegate by using a lambda expression. 
    Task taskA = new Task( () => Console.WriteLine("Hello from taskA."));
    // Start the task.
    taskA.Start();

    // Output a message from the calling thread.
    Console.WriteLine("Hello from thread '{0}'.", 
                  Thread.CurrentThread.Name);
    taskA.Wait();
}

public static void Main()
{
    Thread.CurrentThread.Name = "Main";

    // Define and run the task.
    Task taskA = Task.Run( () => Console.WriteLine("Hello from taskA."));

    // Output a message from the calling thread.
    Console.WriteLine("Hello from thread '{0}'.", 
                      Thread.CurrentThread.Name);
    taskA.Wait();
}

public static void Main()
{
    Thread.CurrentThread.Name = "Main";

    // Better: Create and start the task in one operation. 
    Task taskA = Task.Factory.StartNew(() => Console.WriteLine("Hello from taskA."));

    // Output a message from the calling thread.
    Console.WriteLine("Hello from thread '{0}'.", 
                    Thread.CurrentThread.Name);

    taskA.Wait();                  
}

난 그냥 MS가 같은 TPL 그들은 때문에 모든 작업을 작업을 실행하는 3 개 가지 방법을 제공합니다 이유를 이해하지 않습니다 Task.Start(), Task.Run()그리고 Task.Factory.StartNew().

내게된다 텔 Task.Start(), Task.Run()그리고 Task.Factory.StartNew()모두 같은 목적으로 사용하거나 서로 다른 의미를 가지고 있습니까?

때 하나 개 사용한다 Task.Start(), 때 하나를 사용해야 Task.Run()언제해야 하나 개 사용을 Task.Factory.StartNew()?

예를 들어 시나리오별로 실제 사용법을 자세히 이해하도록 도와주십시오. 감사합니다.


여기에 그리고 여기에 더 새로운 Task.Run것을 설명 하는 오래된 기사가 있습니다 -아마도 이것이 귀하의 질문에 대답 할 것입니다.)
Carsten

다음Task.Start실제로 유용한 예입니다 .
noseratio

답변:


171

Task.RunTask.Factory.StartNew특정 안전 인수 를 사용 하는 축약 형입니다 .

Task.Factory.StartNew(
    action, 
    CancellationToken.None, 
    TaskCreationOptions.DenyChildAttach, 
    TaskScheduler.Default);

.Net 4.5에 추가되어 점차 빈번하게 사용 async및 오프로드 작업을 수행 할 수 ThreadPool있습니다.

Task.Factory.StartNew(.Net 4.0에서 TPL과 함께 추가됨)이 훨씬 강력합니다. Task.Run충분하지 않은 경우 , 예를 들어 사용하고 싶을 때만 사용해야합니다 TaskCreationOptions.LongRunning(대리자가 비동기 일 때는 불필요합니다. 내 블로그에 대한 자세한 내용 : LongRunning은 쓸모없는 Task.Run with async-await ). Task.Run vs Task.Factory.StartNewTask.Factory.StartNew 에서 자세히 알아보기

그렇게 할만한 타당한 이유가없는 한 Task, 전화를 걸지 Start()마십시오. 작업을 작성해야하지만 일부는 작성하지 않고 일정을 설정하지 않아도되는 일부 부품이있는 경우에만 사용해야합니다. 그것은 거의 적절한 해결책이 아니며 위험 할 수 있습니다. 더 많은 대 "Task.Factory.StartNew" "새 작업 (...). 시작"

결론적으로, 대부분 사용하고 Task.Run, 사용 Task.Factory.StartNew하지 않으면 안됩니다 Start.


5
u는 "태스크를 작성하지 말고 Start ()를 호출하지 마십시오"라고 말하면서 Task.Start ()에 의해 발생할 수있는 적절한 쓰기로 리디렉션합니다. 당신이 그것을 피하기 위해 말하기 때문에 세부 사항이 필요합니다. 답변 감사합니다.
Mou


1
@Mou Task.Start는 대부분 유형을 상속받을 수있는 곳입니다.
유발 이츠 차 코프

1
@Mou 한 번만 호출되도록 동기화가 필요하므로 비효율적입니다. 다른 옵션은 그렇지 않습니다.
i3arnon

2
@Mou 아마도이 문제를 설명하는 게시물을 읽어야 할 것입니다 blogs.msdn.com/b/pfxteam/archive/2010/06/13/10024153.aspx
i3arnon

2

짧은 답변 :

중첩 된 하위 작업을 사용하지 않고 항상 스레드 풀 에서 작업을 실행 하려면을 사용하는 것이 좋습니다 Task.Run.

긴 대답 :

Task.Run그리고 Task.Factory.StartNew모두 작성에 대한 지원을 제공하고, 우리가 만들 필요가 없습니다 스케줄링 작업은 객체 Task와 전화를Start()

Task.Run(action);

다음과 같습니다.

Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);

Task.Factory.StartNew(action);

다음과 같습니다.

Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Current);

Task.Run사용 TaskCreationOptions.DenyChildAttach은 하위 태스크를 상위에 첨부 할 수 없음 TaskScheduler.Default을 의미하며 스레드 풀에서 태스크를 실행하는 태스크는 항상 태스크를 실행하는 데 사용됩니다.

Task.Factory.StartNew를 사용 TaskScheduler.Current하여 현재 스레드의 스케줄러를 의미 TaskScheduler.Default하지만 항상 그런 것은 아닙니다.

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