【问题标题】:Set a timeout for a scala method为 Scala 方法设置超时
【发布时间】:2018-02-11 20:19:45
【问题描述】:

我正在尝试为方法设置超时。我在测试中有以下代码。 f 的返回值是我定义的一个特殊类型。它返回Interval(Int, Int)

val f = evalfunc (a, b)

evalfunc 正在使用外部单纯形求解器。有时它会卡在这里。我想为此设置一个超时。我在this 之后尝试了未来超时。

def runWithTimeout[T](timeout: Long)(f: => T) : Option[T] = {
 Await.result(Future(f), timeout seconds).asInstanceOf[Option[T]] } 

def runWithTimeout[T](timeout: Long, default: T)(f: => T) : T = { runWithTimeout(timeout)(f).getOrElse(default)}

val f = runWithTimeout(300){evalfunc(a, b)}

但它说,tools.Interval 不能转换为 scala.Option。如何在此功能中添加计时器?我需要 val f as Interval(Int, Int) 然后我在 f 上做一些计算。

我的问题是我尝试使用链接中给出的解决方案。就我而言,我正在尝试为返回 Interval(Int, Int) 的方法添加超时,它说它需要 scala.Option。

【问题讨论】:

  • 我已经看到了这个链接的答案,并在我的问题中提到了这一点。请检查问题中的链接。
  • 只需将Option[T] 替换为T,然后移除演员表。
  • btw .asInstanceOf 通常是出现问题的征兆

标签: scala future


【解决方案1】:

您为什么首先将其转换为Optiondocumentation for Await.result 声明 result[T] 的返回类型是 T,而不是 Option[T]

您可以从中创建一个Option[T],但为此,您必须捕获TimeoutException,如果result 方法在指定的时间限制内没有成功,则抛出该TimeoutException

不妨试试这样的:

import scala.concurrent._
import scala.concurrent.duration._

def runWithTimeout[T]
  (timeout: Long)
  (f: => T)
  (implicit ec: ExecutionContext)
: Option[T] = {
  try {
    Some(Await.result(Future(f), timeout.seconds))
  } catch {
    case e: TimeoutException => None
  }
}

请注意,所有这些超时和等待的东西只影响正在等待的程序部分。它不会以任何方式影响您复杂的数值过程f的执行:一旦启动,它无论如何都会运行,如果它在同一个JVM中运行,则无法停止它,因为JVM不是一个操作系统。如果您希望能够真正停止f 的执行,那么您有两种选择:

  • f合作,即它应该偶尔检查是否仍然需要结果,如果由于超时不再需要结果,则停止。
  • 在 JVM 之外将f 作为单独的进程运行,超时后使用操作系统的工具将其杀死。

【讨论】:

  • 非常感谢。它超时了,但是是的,我需要停止执行f。我会尝试单独运行它。
猜你喜欢
  • 1970-01-01
  • 2011-12-02
  • 2021-02-09
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-24
相关资源
最近更新 更多