1

GParsのフォーク/ジョインを使用しています。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 に答える