我有一个代码块,这是对taskadoc中给出的代码段的稍作修改[原始:https://monix.io/api/3.0/monix/eval/tasklocal.html]。
我的代码只是替换了内联任务(在理解中),引用了在该任务之外定义的任务理解的范围。不幸的是,当我的任务运行时,它看不到绑定,而是看到原始值(0)。我希望我的稍微修改的代码(下图)能产生与Scaladoc的摘要相同的结果。但出乎意料的是,我获取" value3:4",而不是value3:200。我对tlocal的引用似乎正在获得该线程local-ish变量的不同'版本'那是默认的,对绑定一无所知。
代码
class MonixTests extends FlatSpecLike with Matchers {
"TaskLocal" should "not make me sad " in {
val tlocal: Task[TaskLocal[Int]] = TaskLocal(0)
val readTask: Task[Int] =
tlocal.flatMap {
taskLocal: TaskLocal[Int] =>
taskLocal.read.map{ i => i * 2 }
}
val task: Task[Unit] =
for {
local <- tlocal
value1 <- local.read // value1 == 0
_ <- local.write(100)
value2 <- local.read // value2 == 100
value3 <- local.bind(200)(readTask)
value4 <- local.read // value4 == 100
_ <- local.clear
value5 <- local.read // value5 == 0
} yield {
// Should print 0, 100, 400, 100, 0 -- but value3 is not 400, but 4
println("value1: " + value1)
println("value2: " + value2)
println("value3: " + value3)
println("value4: " + value4)
println("value5: " + value5)
}
import monix.execution.Scheduler.Implicits.global
implicit val opts = Task.defaultOptions.enableLocalContextPropagation
task.runToFutureOpt
println(" TRY AGAIN a slightly different way, but no success ;^( ")
val task3: Task[Unit] =
for {
local <- tlocal
value1 <- local.read // value1 == 0
_ <- local.write(100)
value2 <- local.read // value2 == 100
value3 <- local.bind(200)(readTask)
value44 <- local.bind(200) (
tlocal.flatMap {
taskLocal: TaskLocal[Int] =>
taskLocal.read.map{i => i * 2}
}
)
_ <- local.clear
value5 <- local.read // value5 == 0
} yield {
// Should print 0, 100, 400, 100, 0 -- but value3 is not 400, but 4
println("value1: " + value1)
println("value2: " + value2)
println("value3: " + value3)
println("value4: " + value44)
println("value5: " + value5)
}
task3.runToFutureOpt
}
理由:
我要这样做的原因是因为我想将一个值绑定到我的线程本地,然后创建一个任务链这些任务中的某些任务拉动了我所理解的线程本地的当前值,而这些任务是由TaskLocal"正面"的。而且,公正需要明确的是,其中一些任务是在我的代码库中的其他类中定义的,而不是在任何特定的理解范围内都插入。
谢谢!/chris
我现在很高兴,因为我想出了如何或多或少要做我想做的事情。下面的解决方案使用直接向上"本地"而不是任务网。但是它具有所需的效果在代码块中可见界值(200),该代码块引用了线程本地变量'tlocal'。
我真的不需要在"任务上下文"中做事,所以这使我走上了正确的轨道。
"TaskLocal" should "not make me sad today" in {
import monix.execution.misc.Local
val tlocal = Local(0)
def doubleTlocal: Int = {tlocal.get * 2}
val value1 = tlocal.get // value1 == 0
tlocal.update(100)
val value2 = tlocal.get // value2 == 100
val value3 = tlocal.bind(200)(doubleTlocal)
val value4 = tlocal.get // value4 == 100
tlocal.clear
val value5 = tlocal.get // value5 == 0
println("value1: " + value1)
println("value2: " + value2)
println("value3: " + value3)
println("value4: " + value4)
println("value5: " + value5)
}