Groovy GPars forkOffChild异常处理
我正在使用GPAR的fork/join。当我在调用forkOffChild后抛出异常时,它会被掩埋 例如:Groovy GPars forkOffChild异常处理,groovy,gpars,Groovy,Gpars,我正在使用GPAR的fork/join。当我在调用forkOffChild后抛出异常时,它会被掩埋 例如: def myRecursiveClosure = { boolean top -> try { if (!top) { throw new RuntimeException('child had a problem') } else { forkOffChild(false) }
def myRecursiveClosure = { boolean top ->
try {
if (!top) {
throw new RuntimeException('child had a problem')
} else {
forkOffChild(false)
}
} catch (Exception exc) {
println 'Exception handled internally'
throw exc
}
}
try {
GParsPool.withPool {
GParsPool.runForkJoin(true, myRecursiveClosure)
}
} catch (Exception exc) {
println 'Exception handled externally'
throw exc
}
在这里,我设置了一个标志,以便知道闭包已被递归调用。然后,我抛出一个异常,该异常被“内部”捕获,但重新抛出的异常永远不会被“外部”捕获。所以我不知道那个分叉的孩子失败了
我也尝试了异常处理程序,但它似乎也没有被调用
这是预期的行为,还是我做错了什么?有什么策略可以帮助解决这个问题吗?我不能让孩子默默地失败
谢谢 这里重要的一点是forkOffChild()不会等待孩子运行。它只是安排执行。因此,您不能期望forkOffChild()方法传播来自子级的异常,因为它们可能在父级从forkOffChild()方法返回后很久才会发生 但是,通常情况下,父级对子级计算的结果感兴趣,因此在分叉后的某个时刻,它会使用getChildrenResults()方法收集结果。这将返回一个计算值列表或重新抛出潜在异常 此代码段显示了获得预期行为的最小更改:
try {
if (!top) {
throw new RuntimeException('child had a problem')
} else {
forkOffChild(false)
println childrenResults
}
} catch (Exception exc) {
println 'Exception handled internally'
throw exc
}
谢谢我看了你们的例子,瓦茨拉夫,看到了这个。呃,在那个里超时了。你的解释有道理。我试过了,它成功了。我假设这也是异步函数的正确方法。在测试之后,我可以看到并行集合确实向调用方抛出了它,我假设它们在内部执行这种“获取结果”。它们似乎最终会消亡,我想如果出现异常,没有什么好方法可以立即杀死所有线程?嗯,这里有一个相关的问题。。。WhenBond不会像get()那样抛出异常,并且不会调用闭包代码。如何处理异步函数和绑定时的异常?如果你愿意,我会发布一个单独的问题。谢谢是的,如果发生异常,并行集合不会取消正在进行的计算。异步函数会将异常绑定到返回的承诺,因此get()会重新抛出它,whenBound()会将它传递给处理程序:result.whenBound{if(it instanceOf exception)…}