I've written an asynchronous retry method as an answer for this question. I'd like to get your opinion of the implementation and whether there are better ways to implement this. You could also implement this with async-await
but I thought this would be a more efficient implementation.
public static Task RetryAsync(Func<bool> retryFunc, CancellationToken cancellationToken, int retryInterval)
{
var tcs = new TaskCompletionSource<object>();
var timer = new Timer((state) =>
{
var taskCompletionSource = (TaskCompletionSource<object>)state;
if (!taskCompletionSource.Task.IsCompleted)
{
try
{
if (cancellationToken.IsCancellationRequested)
{
taskCompletionSource.SetException(new TaskCanceledException("RetryAsync cancelled"));
}
else if (retryFunc())
{
taskCompletionSource.SetResult(null);
}
}
catch (Exception ex)
{
taskCompletionSource.SetException(ex);
}
}
}, tcs, 0, retryInterval);
//// Once the task is complete, dispose of the timer so it doesn't keep firing.
tcs.Task.ContinueWith(t => timer.Dispose(),
CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously,
TaskScheduler.Default);
return tcs.Task;
}