Scala Monix,如何杀死正在运行或预定的任务

时间:2018-05-14 03:44:07

标签: scala asynchronous concurrency future monix

我正在使用Monix进行异步任务工作流程。

我们如何杀死正在运行的Task

Task{ println("sleep")
      Thread.sleep(200)
      println("effect") }
.doOnCancel(Task(println("canceled")))
.timeout(100.milli) // timeout will do cancel
.runOnComplete(println)

@> Failure(java.util.concurrent.TimeoutException: Task timed-out after 100 milliseconds of inactivity) sleep canceled effect <--- what !? , task is running. Isn't it canceled !?

我认为目前的解决方案很丑陋(标志检查阻碍了代码重用):

var flag=true
Task{ 
      println("sleep")
      Thread.sleep(200)
      if (flag)
        println("effect") 
}
.doOnCancel(Task{ flag=false; println("canceled") })
.timeout(100.milli) // timeout will do cancel

如果不可能,我们如何杀死未安排的Task

我失败的尝试是:

Task{ println("sleep"); Thread.sleep(200) }
.map{ _ => println("effect") }
.doOnCancel(Task(println("canceled")))
.timeout(100.milli) // timeout will do cancel
.runOnComplete(println)

可悲的是,它仍然显示取消发生后的效果。我希望可以取消已安排和尚未运行的任务(.map(...)是另一个Task,对吧?)

2 个答案:

答案 0 :(得分:2)

如果你不使用Thread.sleep(与Monix的内部混淆),但Task.sleep,事情就好了。

Task
  .defer {
    println("start")
    Task.sleep(1000.millis)
  }
  .map(_ => println("effect"))
  .timeout(10.millis)
  .doOnCancel(Task(println("canceling")))

现在,问题是您的实际用例是什么,因为我确定您仅使用Thread.sleep进行说明。

答案 1 :(得分:0)

如果它是任务链,我找到了一个解决方案:

Task{println("start");Thread.sleep(1000)}
 .asyncBoundary
 .map{_=> println("effect")}
 .doOnCancel(Task(println("canceling")))
 .timeout(10.milli)
 .executeWithOptions(_.enableAutoCancelableRunLoops)
 .runOnComplete(println)

参考:https://github.com/monix/monix/issues/226

但我希望有一种简单的方法来中断任务,而不是使用闭包或拆分和链接任务。