I require a method that will throw an exception if a function that is passed into it is not completed before X minutes.
This is my original code:
public class Poller : IPoller
{
public async Task<bool> RunTimedFunction(string taskName,
int timeoutMs,
Func<bool> pollMethod)
{
var canPoll = true;
var returnValue = false;
var watch = System.Diagnostics.Stopwatch.StartNew();
var t = Task.Factory.StartNew(() =>
{
watch.Start();
returnValue = pollMethod();
canPoll = false;
return returnValue;
});
while (canPoll)
{
if(watch.ElapsedMilliseconds >= timeoutMs)
throw new TimeoutException(String.Format("Task: {0} has timed out", taskName));
}
await t;
return returnValue;
}
}
I can test that it works with the following:
[Test]
[ExpectedException(typeof(TimeoutException))]
public async Task Poller_PollTimeout()
{
var name = "Timeout";
var timeout = 10;
var func = new Func<bool>(() =>
{
Thread.Sleep(1000);
return true;
});
var t = _poller.Poll(name, timeout, func);
await t.ContinueWith((task) =>
{
if (task.Exception != null)
throw task.Exception.InnerException;
});
}
From suggestions I now have:
public class Poller : IPoller
{
public async Task<T> RunTimedFunction<T>(string taskName,
int timeoutMs,
Func<T> pollMethod)
{
var timerTask = Task.Delay(timeoutMs);
var funcTask = Task.Run(pollMethod);
var firstFinished = await Task.WhenAny(timerTask,
funcTask);
if(firstFinished == timerTask)
throw new TimeoutException(String.Format("Task: {0} has timed out", taskName));
return funcTask.Result;
}
}