如果传递给它的函数在X分钟之前没有完成,我需要一个抛出异常的方法。
这是我的原始代码:
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;
}
}
我可以测试它是否适用于以下内容:
[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;
});
}
根据我现在提出的建议:
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;
}
}
答案 0 :(得分:3)
怎么样
public async Task<Tuple<int, T>> TimeFunc<T>(
Func<T> target,
int timeoutMilliseconds)
{
var timeoutTask = Task.Delay(timeoutMilliseconds);
var timer = Stopwatch.StartNew();
var funcTask = Task.Run(() => target());
var first = await Task.WhenAny(new[] { timeoutTask, funcTask });
timer.Stop();
if (first == timeoutTask)
{
throw new TimeoutException();
}
return Tuple.Create(timer.ElapsedMilliseconds, funcTask.Result);
}