그래서 최근에 .ContinueWith for Tasks를 사용하는 방법이 적절한 사용 방법이 아니라는 말을 들었습니다. 나는 아직 인터넷에서 이것에 대한 증거를 찾지 못했기 때문에 여러분들에게 물어보고 답이 무엇인지 볼 것입니다. 다음은 .ContinueWith를 사용하는 방법의 예입니다.
public Task DoSomething()
{
return Task.Factory.StartNew(() =>
{
Console.WriteLine("Step 1");
})
.ContinueWith((prevTask) =>
{
Console.WriteLine("Step 2");
})
.ContinueWith((prevTask) =>
{
Console.WriteLine("Step 3");
});
}
이제 저는 이것이 간단한 예이며 매우 빠르게 실행된다는 것을 알고 있지만 각 작업이 더 긴 작업을 수행한다고 가정합니다. 그래서 제가들은 것은 .ContinueWith에서 prevTask.Wait (); 그렇지 않으면 이전 작업이 완료되기 전에 작업을 수행 할 수 있습니다. 그게 가능할까요? 두 번째 및 세 번째 작업은 이전 작업이 완료된 후에 만 실행될 것이라고 가정했습니다.
코드 작성 방법을 들었습니다.
public Task DoSomething()
{
return Task.Factory.StartNew(() =>
{
Console.WriteLine("Step 1");
})
.ContinueWith((prevTask) =>
{
prevTask.Wait();
Console.WriteLine("Step 2");
})
.ContinueWith((prevTask) =>
{
prevTask.Wait();
Console.WriteLine("Step 3");
});
}
답변
Ehhh …. 현재 답변 중 일부가 누락 된 것 같습니다. 예외가 발생하면 어떻게됩니까?
Wait
연속을 호출하는 유일한 이유 는 연속 자체의 선행 항목에서 잠재적 인 예외를 관찰하는 것입니다. Result
a의 경우 액세스 한 경우 Task<T>
와 Exception
속성에 수동으로 액세스 한 경우에도 동일한 관찰이 발생합니다 . 솔직히, 예외가 있으면 불필요한 오버 헤드가 발생하는 리 레이즈 대가를 지불 Wait
할 Result
것이기 때문에 저는 전화 하거나 액세스 하지 않을 것입니다. 대신 당신은 단지 IsFaulted
선행 에서 속성을 확인할 수 있습니다 Task
. 또한 만에 하나 성공 또는 실패에 따라 졌지 여러 형제 연속 요청에 체인에 의해 갈래의 워크 플로우를 만들 수 있습니다 TaskContinuationOptions.OnlyOnRanToCompletion
및 TaskContinuationOptions.OnlyOnFaulted
.
이제 계속되는 선행 항목의 예외를 관찰 할 필요는 없지만 “1 단계”가 실패한 경우 워크 플로가 진행되는 것을 원하지 않을 수 있습니다. 이 경우 : 지정하는 TaskContinuationOptions.NotOnFaulted
당신에게 ContinueWith
전화하는 것은 이제까지도 발사에서 연속 논리를 방지합니다.
자신의 연속 작업이 예외를 관찰하지 못하는 경우이 전체 워크 플로가 완료되기를 기다리는 사람이이를 관찰 할 수 있습니다. 어느 그들이있어 Wait
온 보내고 Task
상류하거나 완료되면 알고 자신의 계속에 압정으로 고정했다. 후자의 경우, 이들의 연속은 앞서 언급 한 관찰 논리를 사용해야합니다.
답변
올바르게 사용하고 있습니다.
대상 Task가 완료 될 때 비동기 적으로 실행되는 연속을 만듭니다 .
출처 : Task.ContinueWith 메서드 (Action as MSDN)
전화를 갖는 prevTask.Wait()
모든에 Task.ContinueWith
즉, 실제로 코드의 특정 비트가 무엇을하는지 이해하지 않기 때문에 “슈퍼 확인아요”로 뭔가를하고 – 호출하는 것은 불필요한 로직을 반복하는 이상한 방법처럼 보인다. ArgumentNullException
어쨌든 던져졌을 곳 을 던지기 위해 null을 확인하는 것과 같습니다 .
그래서, 누가 당신에게 틀렸다고 말했고 아마도 왜 Task.ContinueWith
존재 하는지 이해하지 못할 것 입니다.
답변
누가 그랬어?
MSDN 인용 :
대상 Task가 완료 될 때 비동기 적으로 실행되는 연속을 만듭니다.
또한 이전 작업이 완료되기를 기다리지 않는 경우 계속 작업 의 목적은 무엇입니까?
직접 테스트 할 수도 있습니다.
Task.Factory.StartNew(() =>
{
Console.WriteLine("Step 1");
Thread.Sleep(2000);
})
.ContinueWith((prevTask) =>
{
Console.WriteLine("I waited step 1 to be completed!");
})
.ContinueWith((prevTask) =>
{
Console.WriteLine("Step 3");
});
답변
보내는 사람 은 MSDN 에Task.Continuewith
반환 된 Task는 현재 작업이 완료 될 때까지 실행되도록 예약되지 않습니다. continuationOptions 매개 변수를 통해 지정된 기준이 충족되지 않으면 연속 작업이 예약되지 않고 취소됩니다.
첫 번째 예에서 예상하는 방식이 올바른 방식이라고 생각합니다.
답변
답변
액세스 Task.Result
하면 실제로 다음과 유사한 논리를 수행합니다.task.wait
답변
나는 이미 말한 많은 것을 반복 할 prevTask.Wait()
필요가 없습니다 .
더 많은 예제를 보려면 Continuation Tasks를 사용하여 Chaining Tasks 로 이동 하고 좋은 예제가있는 Microsoft의 또 다른 링크를 참조하십시오.