首页 > 解决方案 > Scala 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

如果不可能,我们如何在 not-yet-ran 时杀死计划的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,对吗?)

标签: scalaasynchronousconcurrencyfuturemonix

解决方案


If you don't use Thread.sleep (which messes with the internals of Monix), but Task.sleep, things are working just fine.

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

Now, the question is what's your actual use case, because I'm sure you used Thread.sleep just for illustration purposes.


推荐阅读