1

以下は疑似コードです。

myGoto:
try
{
   // do some db updating
   myDB.doOptimisticConcurrency();

} catch (MyConcExeption ex) {

   if (tried < fiveTimes) {
       myDB.Refresh();
       tried++;
       goto myGoto;
   }

}

1 つのメソッドに複数の try-catch ブロックがあり、例外がスローされるたびにメソッドを最初から再呼び出ししたくありません。この状況での使用はgoto許容されますか?

4

6 に答える 6

16

次のように変更できます。

while (tried < fiveTimes)
try
{
   // do some db updating
   myDB.doOptimisticConcurrency();
   break;
}
catch (MyConcExeption ex)
{
   tried++;
   myDB.Refresh();
}
于 2010-10-17T20:05:31.997 に答える
13

「goto」は使用しませんが、少しヘルパーメソッドを作成することをお勧めします。例えば:

public static void TryMultiple<E>(Action action, int times) where E : Exception
{
    E lastException = null;
    for (int i = 0; i < times; i++)
    {
        try
        {
            action();
            return; // Yay, success!
        }
        catch (E exception)
        {
            // Possibly log?
            lastException = exception;
        }
    }
    throw new RetryFailedException("Retry failed " + times + " times",
                                   lastException);
}

これはソリューションのスケッチにすぎません。それに応じて調整する必要があります。とにかく、これにより、基本的に、再利用可能な方法で、半ば受け入れられた例外に直面して再試行を実行できます。おそらくラムダ式を使用してアクションを表現するか、単一のメソッド呼び出しのメソッドグループを使用する場合があります。

TryMultiple<MyConcurrencyException>(myDB.doOptimisticConcurrency, 5);
于 2010-10-17T20:07:10.877 に答える
3

ループを使用するだけで済みます。

于 2010-10-17T20:05:00.350 に答える
2

gotoを使用することはほとんど受け入れられません。それはスパゲッティコードにつながり、コードを読みにくくします。

あなたの場合、単純なループでコードが読みやすくなります。

代替テキスト

于 2010-10-17T20:02:49.537 に答える
1

状況が例外的でない場合は、例外をスローするべきではありません。そのメソッドに再試行引数を追加し、再試行回数を超えた場合にのみ内部的に例外をスローしませんか?

編集:他の人が示唆しているように、ループもより良い代替手段です。ただし、これはメソッドのように見えます。変更できないライブラリにラップされたメソッドではありません。私が正しければ、再試行パラメーターを使用して、すべての再試行が失敗した場合にのみ例外をスローします。このメソッドが最初の試行で失敗することがあると予想される場合は、例外ではありません。

于 2010-10-17T20:05:50.023 に答える
-1

これははるかに優れています:

private void MyMethod()
{
   MyMethod(5);
}    

private void MyMethod(int triesLeft)
{
   if(triesLeft == 0)
      return;  // or throw

   try
   {
      // do some db updating
      myDB.doOptimisticConcurrency();
   }       
   catch (MyConcExeption ex) 
   {
       myDB.Refresh(); 
       MyMethod(triesLeft - 1);
   }
}
于 2010-10-17T20:07:21.610 に答える