开发者

Is using "goto" acceptable in this situation?

开发者 https://www.devze.com 2023-01-20 03:43 出处:网络
The following is pseudocode: myGoto: try { // do some db updating myDB.doOptimisticConcurrency(); } catch (MyConcExeption ex) {

The following is pseudocode:

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

} catch (MyConcExeption ex) {

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

}

I have several try-catch blocks in one method, and I don't want to reinvoke my method from the beginning for every thrown exception. Is using go开发者_运维问答to acceptable in this situation?


You can change it to:

while (tried < fiveTimes)
try
{
   // do some db updating
   myDB.doOptimisticConcurrency();
   break;
}
catch (MyConcExeption ex)
{
   tried++;
   myDB.Refresh();
}


I wouldn't use "goto" - but you might want to write a little helper method. For example:

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);
}

That's just a sketch of the solution - you'll want to adapt it accordingly. Anyway, this basically lets you perform retries in the face of a semi-accepted exception in a reusable manner. You'll probably use a lambda expression to express the action, or sometimes just a method group for a single method call:

TryMultiple<MyConcurrencyException>(myDB.doOptimisticConcurrency, 5);


You could just use a loop.


Using goto is almost never acceptable, it leads to spaghetti code and get your code less readable.

In your case a simple loop would make your code more readable.

Is using "goto" acceptable in this situation?


You shouldn't be throwing an exception if the situation is not, well, exceptional. Why don't you add a retry argument to that method and throw the exception internally only if the retry count is exceeded?

EDIT: Like others have suggested, a loop is a better alternative as well. However, that looks like your method, not a method wrapped in some library that you can't modify. If I am correct, I would still go with the retry parameter and only throw an exception if all retries fail. If you expect that this method will sometimes fail on the first attempt that should not be an exception.


This is much better:

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);
   }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号