await
使這個超級簡單:
public async Task TimedLoop(Action action,
CancellationToken token, TimeSpan delay)
{
while (true)
{
token.ThrowIfCancellationRequested();
action();
await Task.Delay(delay, token);
}
}
沒有async
(但仍只使用TPL)這是一個有點混亂。我通常通過將本身附加到類型爲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;
}
我也會將取消標記傳遞給'Delay'方法。 –
@EliArbel編輯。 – Servy
似乎是濫用迭代器來模擬異步的好用例。有一個庫。 – usr