1

我正在使用 GPars 的 fork/join。当我在调用 forkOffChild 后抛出异常时,它会被掩埋。

例如:

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
}

在这里,我设置了一个标志,因此我知道闭包已被递归调用。然后,我抛出一个异常,它被“内部”捕获,但重新抛出从未被“外部”捕获。所以我不知道分叉的孩子失败了。

我也尝试了异常处理程序,但它似乎也没有被调用。

这是预期的行为,还是我做错了什么?有什么策略可以帮助解决这个问题吗?我不能让孩子默默地失败。

谢谢!

4

1 回答 1

3

这里重要的部分是 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
    }
于 2012-11-16T10:45:09.563 回答