최소한의 커플 링으로 많은 수의 작업자를 설정하려고하지만 C# async
및 작업을 사용하고 싶습니다. 모든 작업이 완전히 비동기적인 것은 아닙니다 (일부는 완전히 동기식입니다). 이렇게하기위한 동기는 비즈니스 로직을 실행하는 간단한 메소드를 만들고, System.Threading.Tasks.Task
API를 사용하여 이들을 연쇄 적으로 연결하여 주문 개념을 유지하려는 것입니다. 기본적으로, 나는 첫번째 작업을 만들고, 몇개의 연속을 등록하고, 마지막 작업이 완료되기를 기다리고 싶다.이 작업이 일찍 돌아 오는 이유는 무엇입니까? 내가 잘못 했니?
void Main()
{
var worker = new Worker();
var work = worker.StartWork(1, 2000);
work.ConfigureAwait(false);
var final = work.ContinueWith(_ => worker.StartWork(2, 0))
.ContinueWith(ant => worker.StartWork(3, 1500));
var awaiter = final.ContinueWith(_ => Tuple.Create(_.Id, _.Status));
Console.WriteLine("\"final\" completed with result {0}", awaiter.Result);
Console.WriteLine("Done.");
}
// Define other methods and classes here
class Worker {
internal async Task StartWork(int phase, int delay) {
Console.WriteLine("Entering phase {0} (in Task {1}) with {2} milliseconds timeout.", phase, Task.CurrentId, delay);
if (delay > 0)
{
Console.WriteLine("Do wait for {0} milliseconds.", delay);
await Task.Delay(delay);
}
Console.WriteLine("ending phase {0}", phase);
}
}
문제는 소위 awaiter
작업에 대기을 기다리고 것 같다 :
여기에 내가 무엇을 원하는 경우에도 작동하는지 확인하기 위해 단지 내장 된 간단한 프로토 타입입니다
Entering phase 1 (in Task) with 2000 milliseconds timeout.
Do wait for 2000 milliseconds.
ending phase 1
Entering phase 2 (in Task 769) with 0 milliseconds timeout.
ending phase 2
Entering phase 3 (in Task 770) with 1500 milliseconds timeout.
Do wait for 1500 milliseconds.
"final" completed with result (770, RanToCompletion)
Done.
ending phase 3
이것은 지원되지 않습니까? 나는 Task
API를 꽤 잘 이해한다고 생각했지만 분명히 알지 못합니다. 나는 이것을 async
또는 task를 사용하지 않도록 변환 할 수 있다고 생각하며, 메소드를 완전히 동 기적으로 실행한다. 그러나 이것은 일을하는 나쁜 방법처럼 보인다. 내가 계속 실행하고자하는 것은 정확히 (이것들은 단지 CancellationToken
을 수용합니다). 작업 사이의 메시지에는 특별한 의존성이 없습니다. 단지 주문의 개념을 유지할 필요가 있습니다.
감사합니다.
편집 : 위의 단어 awaiting
을 잘못 사용했습니다. Task.Result
에 액세스하는 것이 완전히 동기임을 알고 있습니다. 내 사과.
편집 2 : 내가 될 것으로 예상 무엇 ContinueWith(_ => worker.Start(2, 0))
를 호출하면 ContinueWith
에 작업을 반환 할 것, 그리고 내 사용자 대리인이 작업을 반환 할 때 TPL은 내부적으로 작업 worker.StartWork
에 의해 반환 기다리고 있습니다 것입니다. ContinueWith
에 대한 오버로드 목록을 보면 분명히 잘못되었습니다. 내가 해결하려고하는 부분은 작업을 스케쥴하는 방법 인 Main
에서 기다리는 방법이다. 모든 대회가 끝나기 전에 나가고 싶지 않습니다.
- 의 주요 방법 세 가지 단계가 있습니다
내가
나는 다음과 같은 요구 사항을 가지고 있었다.ContinueWith
을 사용하는 한 동기 - 단계 1은 세 명의 작업자 (
a
,b
및c
)를 만듭니다. - 2 단계 작업
b
및c
의 완료 후 추가 작업자d
시작되고a
및b
완료시 다른 작업자e
유사한 - 처리를 (종속성 이러한 작업은 순서대로 생성되어야한다는 것이다) 이것은 모든 작업이 완료 될 때까지 계속됩니다.
내가 정확하게 코멘트에 의견을 이해한다면, 나는이 작업을 수행 할 수 있습니다 기본적으로 두 가지 방법이 있습니다
- 이 방법의 동기를 확인하고 연속성을 나 자신을 등록합니다.
async Task
으로 표시된 방법을 그대로두고Task.WhenAll
API와 함께await
키워드를 사용하여 연속을 예약하십시오. 나는이 발생할 것으로 예상 무엇
나는'TaskContinuationOptions.AttachedToParent'를 전달하지 않았기 때문에 문서를 검토하는 이유가 있다고 생각합니다. 그래서'Task' 연속이 detached 상태로 생성됩니다. 우연히 이것을 확인할 수있는 사람이 있습니까? – PSGuy
다른 일이 일어날 것이라고 생각하는 이유에 대해 혼란 스럽습니다. 대부분의 작업을 기다리지 않는 비동기 워크 플로를 만들었습니다. 나는 계속해서 이렇게 말하고있다 : ** 비동기 워크 플로우 **에 대한 시퀀싱 작업이 기다리고있다. 시퀀싱을 거의 수행하지 않았으므로 모든 것이 순차적으로 실행되는 것은 아닙니다. –
당신이 여기에서 일어날 것으로 예상했던 것과 당신이 그것을 기대 한 이유를 더 분명히 말하면, 누군가가 당신의 생각을 잘못 이해했는지 설명 할 수 있습니다. –