PrevTask.Wait ()를 ContinueWith와 함께 사용하는 것이 좋습니다 (태스크 라이브러리에서)?
그래서 최근에 .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가 완료 될 때 비동기 적으로 실행되는 연속을 만듭니다.
Also, what would be the purpose of Continue With if it wasn't waiting for the previous task to be completed?
You can even test it by yourself:
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");
});
From the MSDN on Task.Continuewith
The returned Task will not be scheduled for execution until the current task has completed. If the criteria specified through the continuationOptions parameter are not met, the continuation task will be canceled instead of scheduled.
I think that the way you expect it to work in the first example is the correct way.
You might also want to consider using Task.Run instead of Task.Factory.StartNew.
Stephen Cleary's blog post and the Stephen Toub's post that he references explain the differences. There is also a discussion in this answer.
By Accessing Task.Result
you are actually doing similar logic to task.wait
I will reiterate what many have spoken already, prevTask.Wait()
is unnecessary.
For more examples one can go to Chaining Tasks using Continuation Tasks, yet another link by Microsoft with good examples.
'IT story' 카테고리의 다른 글
Razor 구문은 UI 마크 업에서 강력한 이점을 제공합니까? (0) | 2020.09.09 |
---|---|
명령 줄에서 직접 RabbitMQ 메시지 내용을 볼 수 있습니까? (0) | 2020.09.09 |
Android Studio / IntelliJ에서 Maven 종속성을 가져 오는 방법은 무엇입니까? (0) | 2020.09.09 |
SQL 업데이트 쿼리의 집계 함수? (0) | 2020.09.09 |
angularjs에서 $ http 요청에서 응답이 올 때까지 기다리는 방법은 무엇입니까? (0) | 2020.09.09 |