我想对我正在调用的函数设置时间限制,这样如果它超时,它就会移动到脚本的下一部分(我正在运行source("..."))。该函数是使用 Rcpp 编写的,并且checkUserInterrupt();经常包含在整个过程中。我一直withTimeout在R.utils包中使用 option onTimeout = silent,但是超时仍然是暂停脚本的执行。
然后我在内部运行它tryCatch以NULL在出现任何错误的情况下返回,但它仍然停止我的脚本。我已经包含了一个复制这个问题的简短函数。
#include <Rcpp.h>
#include <chrono>
#include <thread>
using namespace Rcpp;
void sleep_fn(int n) // sleeps for n seconds
{
std::chrono::seconds dura( n );
std::this_thread::sleep_for( dura );
}
// [[Rcpp::export]]
int sleep_for(int n) // sleeps for n seconds and then returns n
{
for (int i = 0; i < n; i++)
{
checkUserInterrupt();
sleep_fn(1);
}
return(n);
}
Run Code Online (Sandbox Code Playgroud)
现在,为了进行比较,让我们运行它以及 R 命令Sys.sleep()。看到这是按预期工作的,但是因为sleep_for它仍然抛出一个异常来停止我的脚本。
> tryCatch(withTimeout(Sys.sleep(10), timeout = 5), error = function(ex) return(NULL))
NULL
> tryCatch(withTimeout(sleep_for(10), timeout = 5), error = function(ex) return(NULL))
Error in .Call(<pointer: 0x108cc17b0>, n) : reached elapsed time limit
> tryCatch(withTimeout(sleep_for(10), timeout = 5, onTimeout = "silent"), error = function(ex) return(NULL))
Error in .Call(<pointer: 0x108cc17b0>, n) : reached elapsed time limit
Run Code Online (Sandbox Code Playgroud)
为什么tryCatch不做我认为应该做的事?有什么我可以做的才能让它发挥作用吗?
(我使用的是 R 版本 4.0.3、Rcpp 版本 1.0.6、R.utils 版本 2.10.1)编辑:并且在 MacOS 11.3.1 上
尝试这个模板,看看它是否有效。我用过它,它默默地存在。
# Timeout is in seconds
# https://www.rdocumentation.org/packages/R.utils/versions/2.7.0/topics/withTimeout
tryCatch(
{
withTimeout(some_function(), timeout = 60)
}
,TimeoutException = function(ex) {
print("Timeout of 60 seconds reached. Function will not be completely run.")
}
)
Run Code Online (Sandbox Code Playgroud)