【发布时间】:2021-07-29 20:53:26
【问题描述】:
我最近在我的 c# 程序中创建了一个函数,它执行一些查询和其他内容,我想知道是否有一种方法可以为该函数设置超时: 特别是如果函数在 10 分钟后没有完全执行,我希望我的程序能够停止。 我也想知道能不能在函数本身内部实现这个控件,以免每次调用都写。
【问题讨论】:
-
我认为CancellationToken 可能是这里的首选工具。
我最近在我的 c# 程序中创建了一个函数,它执行一些查询和其他内容,我想知道是否有一种方法可以为该函数设置超时: 特别是如果函数在 10 分钟后没有完全执行,我希望我的程序能够停止。 我也想知道能不能在函数本身内部实现这个控件,以免每次调用都写。
【问题讨论】:
最好的办法是让方法取一个cancellationToken。它需要经常检查这个令牌,如果它已被取消,则中止。通过创建一个 cancelTokenSource: new CancellationTokenSource(timeout) 并将它拥有的令牌交给函数来创建一个在超时后取消的令牌。对于长时间运行的方法,最好采用取消令牌和某种方式报告进度。
如果无法修改函数,则替代方法可能是这样的:
public async Task<(T Result, bool Completed)> RunTimeoutFunction<T>(Func<T> func, TimeSpan timeout)
{
var funcTask = Task.Run(func);
var timeoutTask = Task.Delay(timeout);
var completedTask = await Task.WhenAny(funcTask, timeoutTask);
if (completedTask == timeoutTask)
{
return (default, false);
}
return (funcTask.Result, true);
}
明显的缺点是即使超时后该函数仍将继续在后台运行。然而,除非可以合作取消该功能,否则这是不可避免的。第三种选择是将函数放在一个单独的进程中,然后您可以在超时后安全地终止该进程。
【讨论】: