【问题标题】:Functions not executing before Sys.sleep()在 Sys.sleep() 之前未执行的函数
【发布时间】:2011-09-05 20:06:00
【问题描述】:

我正在编写一个函数,它需要在 ping 基于 Web 的 API 时捕获速率限制错误。

我正在使用tryCatch 来捕获错误,并在此函数中指定以下错误函数:

error=function(e) {
                warning(paste(e,"\nWaiting an hour for rate limit to reset..."))
                Sys.sleep(3600) # Wait an hour for rate-limit to reset
                return(user.info(user, ego.count))
            }

该功能似乎可以工作,但在检查脚本的输出日志时,我注意到警告消息直到睡眠时间用完后才写入。

我可以在 R 控制台上重现此行为:

print("Drew sucks")
Sys.sleep(10)

Drew sucks 打印到控制台之前十秒钟过去了。在我的函数中,我想在暂停发生之前向用户提供一些关于这个长时间暂停的反馈。

是什么导致了这种行为?

【问题讨论】:

    标签: r system


    【解决方案1】:

    您需要将immediate.=TRUE 设置为您的警告功能,或者设置options(warn=1)可能需要在Sys.sleep()调用之前添加flush.console()(在某些操作系统上)。

    foo <- function() {
      warning("uh-oh...", immediate.=TRUE)
      flush.console()
      Sys.sleep(5)
      "done"
    }
    foo()
    # Warning in foo() : uh-oh...
    # [1] "done"
    

    详细信息在?warning 的“详细信息”部分中详细说明。换句话说,“如果 options(warn=0),警告会在顶级函数完成后被存储和打印;如果 options(warn=1),它们会在它们出现时被打印出来。” p>

    【讨论】:

    • 这可能是一个操作系统问题,但在 OS X 上,该函数在打印警告之前仍会执行 Sys.sleep 调用。
    • 它适用于 Windows 和 Ubuntu(而 Ubuntu 不需要 flush.console())。
    • @DrewConway 它适用于通过终端运行的 OSX。你在图形用户界面吗? (或者更具体地说 - 如果是的话,是哪一个)
    • Drew,我认为您确实发生了一些棘手的事情 - 如果它们都从命令提示符运行,则没有理由让 print() 被睡眠延迟。我刚刚在我的 Mac 上尝试过,但仍然没有看到这种行为。
    • 我认为@Jeff R 很在意。如果我从命令行运行 R 或 R64,我会得到预期的行为。我收到您在使用普通 Mac R GUI 时报告的错误行为。 RStudio 按预期工作。 R 和 GUI 之间必须有一些缓冲,flush.console() 无法修复。
    【解决方案2】:

    为了它,试试吧:

    system(sprintf('sleep %d', seconds))
    

    假设您在路径上有通常的 *NIX sleep 命令。

    【讨论】:

    • 一件事 - 如果使用warning,那么用户可以使用suppressWarnings 不显示消息。有了这个解决方案,就需要另一种方式。
    【解决方案3】:

    默认情况下,警告不会立即打印,而是在顶级函数返回后打印出来。如果您希望它立即打印出来,您可以将警告设置为“1”,如果您希望它停止,您可以设置更高

    【讨论】:

    • 嗯,重新阅读您的帖子后,我不确定我是否真的回答了正确的问题。我以为你是在说你希望 warning() 在被调用时立即打印出来,对吗?
    • 我愿意,但问题似乎不仅仅适用于 warning 呼叫,就像我的 print 示例一样。
    • 这就是让我觉得我可能没有理解你的问题的原因。如果我启动 R 并运行你的打印示例,我会得到打印的输出,然后是延迟。如果为您做同样的事情确实没有在 Sys.sleep() 之前执行 print(),那么正在发生其他事情(例如 Hadley 的回答)。我确实认为无论哪种方式,您都会遇到警告()在函数中的问题。
    【解决方案4】:

    可能与输出缓冲有关 - 请参阅 ?flush.console

    【讨论】:

    • 另一方面,控制台 i/o 永远不会被缓冲。 r 可能是一个例外,但那将是一个惊喜,不是吗?我想看看的另一个计划灵感(doh)......
    • 添加 flush.console() 并不能解决上面“Drew 很烂”示例中的问题。
    猜你喜欢
    • 2013-11-05
    • 2019-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 2019-10-22
    • 2019-10-01
    • 1970-01-01
    相关资源
    最近更新 更多