withTimeout {R.utils} | R Documentation |
Evaluate an R expression and interrupts it if it takes too long.
withTimeout(expr, envir=parent.frame(), timeout, cpu=timeout, elapsed=timeout, onTimeout=c("error", "warning", "silent"), ...)
expr |
The R expression to be evaluated. |
envir |
The |
timeout, cpu, elapsed |
A |
onTimeout |
A |
... |
Not used. |
This method utilizes setTimeLimit
() by first setting the
timeout limits, then evaluating the expression that may or may not
timeout. The method is guaranteed to reset the timeout limits to be
infitely long upon exiting, regardless whether it returns normally
or preemptively due to a timeout or an error.
Returns the results of the expression evaluated.
If timed out, NULL
is returned if onTimeout
was
"warning"
or "silent"
.
If "error"
a TimeoutException
is thrown.
In order to understand when this function works and when it does not,
it is useful to know that it utilizes R's built-in time-out mechanism,
which sets the limits on what is possible and not.
From setTimeLimit
(), we learn that:
"Time limits are checked whenever a user interrupt could occur.
This will happen frequently in R code and during Sys.sleep, but
only at points in compiled C and Fortran code identified by the
code author."
More precisely, if a function is implemented in native code (e.g. C)
and the developer of that function does not check for user interrupts,
then you cannot interrupt that function neither via a user interrupt
(e.g. Ctrl-C) nor via the built-in time out mechanism.
To change this, you need to contact the developer of that piece of
code and ask them to check for R user interrupts in their native code.
Furthermore, it is not possible to interrupt/break out of a "readline"
prompt (e.g. readline
() and readLines
()) using
timeouts; the timeout exception will not be thrown until after the user
completes the prompt (i.e. after pressing ENTER).
Henrik Bengtsson
[1] R help thread 'Time out for a R Function' on 2010-12-06.
http://www.mail-archive.com/r-help@r-project.org/msg119344.html
Internally, eval
() is used to evaluate the expression.
setTimeLimit
()
# - - - - - - - - - - - - - - - - - - - - - - - - - # Function that takes "a long" time to run # - - - - - - - - - - - - - - - - - - - - - - - - - foo <- function() { print("Tic"); for (kk in 1:100) { print(kk); Sys.sleep(0.1); } print("Tac"); } # - - - - - - - - - - - - - - - - - - - - - - - - - # Evaluate code, if it takes too long, generate # a timeout by throwing a TimeoutException. # - - - - - - - - - - - - - - - - - - - - - - - - - res <- NULL; tryCatch({ res <- withTimeout({ foo(); }, timeout=1.08); }, TimeoutException=function(ex) { cat("Timeout. Skipping.\n"); }) # - - - - - - - - - - - - - - - - - - - - - - - - - # Evaluate code, if it takes too long, generate # a timeout returning NULL and generate a warning. # - - - - - - - - - - - - - - - - - - - - - - - - - res <- withTimeout({ foo(); }, timeout=1.08, onTimeout="warning"); # - - - - - - - - - - - - - - - - - - - - - - - - - # Evaluate code, if it takes too long, generate # a timeout, and return silently NULL. # - - - - - - - - - - - - - - - - - - - - - - - - - res <- withTimeout({ foo(); }, timeout=1.08, onTimeout="silent");