从 R 代码调用中断
Invoke interrupt from R code
我有一个通用函数来捕获包中包含的所有异常 logR::tryCatch2
定义为:
tryCatch2 <- function(expr){
V=E=W=M=I=NULL
e.handler = function(e){
E <<- e
NULL
}
w.handler = function(w){
W <<- c(W, list(w))
invokeRestart("muffleWarning")
}
m.handler = function(m){
attributes(m$call) <- NULL
M <<- c(M, list(m))
}
i.handler = function(i){
I <<- i
NULL
}
V = suppressMessages(withCallingHandlers(
tryCatch(expr, error = e.handler, interrupt = i.handler),
warning = w.handler,
message = m.handler
))
list(value=V, error=E, warning=W, message=M, interrupt=I)
}
正如您在最后一行中看到的那样,它 returns 一个或多或少自我描述的列表。
它通过简单的 !is.null
对 tryCatch2
调用后延迟的异常做出真正的反应:
f = function(){ warning("warn1"); warning("warn2"); stop("err") }
r = tryCatch2(f())
if(!is.null(r$error)) cat("Error detected\n")
# Error detected
if(!is.null(r$warning)) cat("Warning detected, count", length(r$warning), "\n")
# Warning detected, count 2
它按预期工作,我可以用我自己的代码做出反应。但在某些情况下,我不想停止也被捕获的 interrupt 进程。目前看来我需要向 tryCatch2
添加额外的参数来控制是否应该捕获中断。所以这个问题询问了一些 invokeInterrupt
函数,我可以通过以下方式使用它:
g = function(){ Sys.sleep(60); f() }
r = tryCatch2(g())
# interrupt by pressing ctrl+c / stop while function is running!
if(!is.null(r$interrupt)) cat("HERE I would like to invoke interrupt\n")
# HERE I would like to invoke interrupt
我认为如果 R 能够捕获一个它应该也能够调用一个。
如何实现 invokeInterrupt
功能?
我可以提出一个依赖于 tools
包的部分解决方案。
invokeInterrupt <- function() {
require(tools)
processId <- Sys.getpid()
pskill(processId, SIGINT)
}
但是,请注意用 pskill
抛出中断信号 (SIGINT
) 似乎不是很可靠。我 运行 通过发送异常并用你的函数捕获它来进行一些测试,如下所示:
will_interrupt <- function() {
Sys.sleep(3)
invokeInterrupt()
Sys.sleep(3)
}
r = tryCatch2(will_interrupt())
在 linux,这在从 R 命令行执行时效果很好。在 windows,R 命令行和 R Gui 在执行这段代码时确实关闭了。更糟糕的是:在 linux 和 windows 上,此代码立即使 Rstudio 崩溃...
因此,如果您的代码要在 Linux 上从 R 命令行执行,此解决方案应该没问题。否则你可能会倒霉...
迟到的答案,但我发现 rlang::interrupt
可以抛出 "user interrupts":
interrupt() allows R code to simulate a user interrupt of the kind that is signalled with Ctrl-C.
It is currently not possible to create custom interrupt condition objects.
来源:?rlang::interrupt
它在内部调用 R API 函数 Rf_onintr
,它是函数 onintr
.
的别名
基本上 interrupt
是 "just" 这些 类 的特殊条件:
interrupt
和 condition
(参见 R source code)。
如果你只是想模拟一个中断来测试 tryCatch
ing(不需要中断 运行 R 语句),通过 类 抛出一个条件就足够了signalCondition
:
interrupt_condition <- function() {
structure(list(), class = c("interrupt", "condition"))
}
tryCatch(signalCondition(interrupt_condition()),
interrupt = function(x) print("interrupt detected"))
# [1] "interrupt detected"
我有一个通用函数来捕获包中包含的所有异常 logR::tryCatch2
定义为:
tryCatch2 <- function(expr){
V=E=W=M=I=NULL
e.handler = function(e){
E <<- e
NULL
}
w.handler = function(w){
W <<- c(W, list(w))
invokeRestart("muffleWarning")
}
m.handler = function(m){
attributes(m$call) <- NULL
M <<- c(M, list(m))
}
i.handler = function(i){
I <<- i
NULL
}
V = suppressMessages(withCallingHandlers(
tryCatch(expr, error = e.handler, interrupt = i.handler),
warning = w.handler,
message = m.handler
))
list(value=V, error=E, warning=W, message=M, interrupt=I)
}
正如您在最后一行中看到的那样,它 returns 一个或多或少自我描述的列表。
它通过简单的 !is.null
对 tryCatch2
调用后延迟的异常做出真正的反应:
f = function(){ warning("warn1"); warning("warn2"); stop("err") }
r = tryCatch2(f())
if(!is.null(r$error)) cat("Error detected\n")
# Error detected
if(!is.null(r$warning)) cat("Warning detected, count", length(r$warning), "\n")
# Warning detected, count 2
它按预期工作,我可以用我自己的代码做出反应。但在某些情况下,我不想停止也被捕获的 interrupt 进程。目前看来我需要向 tryCatch2
添加额外的参数来控制是否应该捕获中断。所以这个问题询问了一些 invokeInterrupt
函数,我可以通过以下方式使用它:
g = function(){ Sys.sleep(60); f() }
r = tryCatch2(g())
# interrupt by pressing ctrl+c / stop while function is running!
if(!is.null(r$interrupt)) cat("HERE I would like to invoke interrupt\n")
# HERE I would like to invoke interrupt
我认为如果 R 能够捕获一个它应该也能够调用一个。
如何实现 invokeInterrupt
功能?
我可以提出一个依赖于 tools
包的部分解决方案。
invokeInterrupt <- function() {
require(tools)
processId <- Sys.getpid()
pskill(processId, SIGINT)
}
但是,请注意用 pskill
抛出中断信号 (SIGINT
) 似乎不是很可靠。我 运行 通过发送异常并用你的函数捕获它来进行一些测试,如下所示:
will_interrupt <- function() {
Sys.sleep(3)
invokeInterrupt()
Sys.sleep(3)
}
r = tryCatch2(will_interrupt())
在 linux,这在从 R 命令行执行时效果很好。在 windows,R 命令行和 R Gui 在执行这段代码时确实关闭了。更糟糕的是:在 linux 和 windows 上,此代码立即使 Rstudio 崩溃...
因此,如果您的代码要在 Linux 上从 R 命令行执行,此解决方案应该没问题。否则你可能会倒霉...
迟到的答案,但我发现 rlang::interrupt
可以抛出 "user interrupts":
interrupt() allows R code to simulate a user interrupt of the kind that is signalled with Ctrl-C. It is currently not possible to create custom interrupt condition objects.
来源:?rlang::interrupt
它在内部调用 R API 函数 Rf_onintr
,它是函数 onintr
.
基本上 interrupt
是 "just" 这些 类 的特殊条件:
interrupt
和 condition
(参见 R source code)。
如果你只是想模拟一个中断来测试 tryCatch
ing(不需要中断 运行 R 语句),通过 类 抛出一个条件就足够了signalCondition
:
interrupt_condition <- function() {
structure(list(), class = c("interrupt", "condition"))
}
tryCatch(signalCondition(interrupt_condition()),
interrupt = function(x) print("interrupt detected"))
# [1] "interrupt detected"