Is it possible to use System.Threading.Task.Task to create a loop of task that can be cancelled?
The flow should start with a Task.Delay(x ms) then continue with userdefined task, then another Task.Delay(y ms) and repeat from the user defined task.
var result = Task.Delay(initialDelay)
.ContinueWith(t => dostuff..)
.ContinueWith what goes here?
Is it even doable using tasks?
I could spin up a timer and be done with it, but using task seems to be the right way to go if I need cancellation, no?
You can cancel an asynchronous operation after a period of time by using the CancellationTokenSource. CancelAfter method if you don't want to wait for the operation to finish.
In this article, we will learn How to cancel or interrupt the Long Running Task using a Cancellationtokensource method in . NET 4.0. In this article, we are going to learn how to cancel or interrupt the Long Running Task using the Cancellationtokensource method in .
If you want to signal to outside users that your task has been cancelled. You can do this by throwing an OperationCancelledException. CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; Task t1 = Task.Factory.StartNew(() =>
await
makes this super easy:
public async Task TimedLoop(Action action,
CancellationToken token, TimeSpan delay)
{
while (true)
{
token.ThrowIfCancellationRequested();
action();
await Task.Delay(delay, token);
}
}
Without async
(but still just using the TPL) it's a bit messier. I generally solve this problem by having a continuation that attaches itself to a variable of type Task
. This works fine, but it can take a second to wrap your head around it. Without await
it may be easier to just use a Timer
instead.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With