想知道为什么 scalaz Task.runAsyncInterruptibly 没有像我期望的那样打扰
wondering why scalaz Task.runAsyncInterruptibly not interrupting as i would expect it to
我一直在看这个演示文稿 https://github.com/indyscala/scalaz-task-intro/blob/master/presentation.md 并且对它使用 Task.runAsyncInterruptibly 呈现的代码片段之一感到困惑(略微修改如下所示):
import java.util.concurrent.atomic.AtomicBoolean
import scalaz.concurrent.Task
import scalaz.{-\/, \/-}
object Junk extends App {
val neverMind = new AtomicBoolean(false)
System.out.println(s"neverMind set to $neverMind on thread ${Thread.currentThread().getName}")
val t = Task {
System.out.println(s" in task run block on thread ${Thread.currentThread().getName}")
Thread.sleep(4000)
System.out.println(s" completed sleep of 40000 ms on thread ${Thread.currentThread().getName}")
}
Task.fork(t).
//t.
runAsyncInterruptibly({
case -\/(t) => t.printStackTrace()
case \/-(()) => println(s"Completed (right) branch of case on thread ${Thread.currentThread().getName}")
}, neverMind)
println("sleeping 1000, then set nevermind to true")
Thread.sleep(1000)
neverMind.set(true)
println("woke up. set cancel=true -- expect stack trace not 'Completed' message")
Thread.sleep(4000)
}
我很困惑,因为我设置了 'cancel' 标志 (neverMind.set(true)),但我没有看到堆栈跟踪。 delay {...} 内的代码块最终打印 'completed successfully'。这很简单,我确定我犯了一个愚蠢的错误..但不确定在哪里!
我向一些同事征求意见,他们指出我原来的例子没有使用 Task.fork() 所以我在同一个线程上做所有事情......哦!好的。我纠正了这一点。还是不行。
提前感谢您提供的任何指导。
我认为答案与 scalaz 的 Task/Future 内的蹦床有关,因为它只检查步骤之间的 cancel
(参见 scalaz 的 Future
内的 listenInterruptibly
。
如果您将任务更改为:
val t = Task.delay(System.out.println(s" in task run block on thread ${Thread.currentThread().getName}"))
.map(_ => Thread.sleep(4000))
.map(_ => System.out.println(s" completed sleep of 40000 ms on thread ${Thread.currentThread().getName}"))
您会看到它在 "completed sleep" 步骤之前被取消。不过,它似乎仍然没有调用打印堆栈跟踪的处理程序。
我一直在看这个演示文稿 https://github.com/indyscala/scalaz-task-intro/blob/master/presentation.md 并且对它使用 Task.runAsyncInterruptibly 呈现的代码片段之一感到困惑(略微修改如下所示):
import java.util.concurrent.atomic.AtomicBoolean
import scalaz.concurrent.Task
import scalaz.{-\/, \/-}
object Junk extends App {
val neverMind = new AtomicBoolean(false)
System.out.println(s"neverMind set to $neverMind on thread ${Thread.currentThread().getName}")
val t = Task {
System.out.println(s" in task run block on thread ${Thread.currentThread().getName}")
Thread.sleep(4000)
System.out.println(s" completed sleep of 40000 ms on thread ${Thread.currentThread().getName}")
}
Task.fork(t).
//t.
runAsyncInterruptibly({
case -\/(t) => t.printStackTrace()
case \/-(()) => println(s"Completed (right) branch of case on thread ${Thread.currentThread().getName}")
}, neverMind)
println("sleeping 1000, then set nevermind to true")
Thread.sleep(1000)
neverMind.set(true)
println("woke up. set cancel=true -- expect stack trace not 'Completed' message")
Thread.sleep(4000)
}
我很困惑,因为我设置了 'cancel' 标志 (neverMind.set(true)),但我没有看到堆栈跟踪。 delay {...} 内的代码块最终打印 'completed successfully'。这很简单,我确定我犯了一个愚蠢的错误..但不确定在哪里!
我向一些同事征求意见,他们指出我原来的例子没有使用 Task.fork() 所以我在同一个线程上做所有事情......哦!好的。我纠正了这一点。还是不行。
提前感谢您提供的任何指导。
我认为答案与 scalaz 的 Task/Future 内的蹦床有关,因为它只检查步骤之间的 cancel
(参见 scalaz 的 Future
内的 listenInterruptibly
。
如果您将任务更改为:
val t = Task.delay(System.out.println(s" in task run block on thread ${Thread.currentThread().getName}"))
.map(_ => Thread.sleep(4000))
.map(_ => System.out.println(s" completed sleep of 40000 ms on thread ${Thread.currentThread().getName}"))
您会看到它在 "completed sleep" 步骤之前被取消。不过,它似乎仍然没有调用打印堆栈跟踪的处理程序。