await
이 슈퍼 쉽게 :
public async Task TimedLoop(Action action,
CancellationToken token, TimeSpan delay)
{
while (true)
{
token.ThrowIfCancellationRequested();
action();
await Task.Delay(delay, token);
}
}
async
없이 (그러나 아직도 단지 TPL을 사용하여)가 조금 지저분합니다. 일반적으로 I 형 Task
의 변수 자체를 첨부 연속을함으로써이 문제를 해결한다. 이것은 정상적으로 작동하지만 머리를 감싸는 데는 몇 초가 걸릴 수 있습니다. await
이 없으면 대신 Timer
을 사용하는 것이 더 쉽습니다.
public Task TimedLoop(Action action,
CancellationToken token, TimeSpan delay)
{
//You can omit these two lines if you want the method to be void.
var tcs = new TaskCompletionSource<bool>();
token.Register(() => tcs.SetCanceled());
Task previous = Task.FromResult(true);
Action<Task> continuation = null;
continuation = t =>
{
previous = previous.ContinueWith(t2 => action(), token)
.ContinueWith(t2 => Task.Delay(delay, token), token)
.Unwrap()
.ContinueWith(t2 => previous.ContinueWith(continuation, token));
};
previous.ContinueWith(continuation, token);
return tcs.Task;
}
또한 취소 토큰을 '지연'메소드로 전달합니다. –
@EliArbel 편집 됨. – Servy
비동기를 시뮬레이트하기 위해 반복자를 잘못 사용하는 좋은 사례 인 것 같습니다. 그것을위한 도서관이 있습니다. – usr