2010-10-17 3 views
1

Ниже псевдокод:Использует «goto» в этой ситуации?

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

} catch (MyConcExeption ex) { 

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

} 

У меня есть несколько примерочных уловы блоков в одном методе, и я не хочу, чтобы reinvoke моего метода с самого начала для каждого брошенного исключения. Использует ли в этой ситуации goto?

+1

Aw. Это больно, пытаясь понять это. – xtofl

+0

On Error Resume Next –

ответ

16

Вы можете изменить его:

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

Примечание. что в конце этого цикла вам нужно будет снова проверить 'try', чтобы узнать, удалось ли ему это сделать. Обычно я предпочел бы исключение после неудачных попыток. –

+1

@Jon - Это верно и для кода в вопросе, я просто показал, как писать его без goto. – Giorgi

+1

Предоставлено, но я думаю, что это стоит указать на недостаток исходного кода. Я подозреваю, что очень редко, что вы действительно хотите продолжать, как будто ничего не получилось после нескольких попыток. –

2

Использование goto почти никогда не является приемлемым, оно приводит к spaghetti code и делает ваш код менее читаемым.

В вашем случае простой цикл сделает ваш код более читаемым.

alt text

+5

Неверно. GOTO может улучшить ваш код, если использовать его разумно. Например, в C это может быть полезно для обертывания кода обработки ошибок в месте на e, если многие вызовы функции могут выйти из строя. Тем не менее, я никогда не нашел необходимости использовать его в C#, и мне не нравится пример OP. Абсолюты редко бывают правильными. –

+0

@Ed Swangren, я закалил свое заявление;) –

+1

Хорошо, теперь я согласен. Удалено мое downvote :) –

3

Вы можете просто использовать цикл.

1

Вы не должны бросать исключение, если ситуация не, ну, исключительный. Почему бы вам не добавить аргумент повтора к этому методу и исключить исключение изнутри только в случае превышения количества повторов?

РЕДАКТИРОВАТЬ: Как и другие, предложенная петля также является лучшей альтернативой. Тем не менее, это выглядит как ваш метод, а не метод, завернутый в какую-либо библиотеку, которую вы не можете изменить. Если я прав, я все равно поеду с параметром повтора и исключим только исключение, если все попытки не пройдут. Если вы ожидаете, что этот метод будет иногда терпеть неудачу с первой попытки, это не должно быть исключением.

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

Это петля! Зачем приносить рекурсию? – SoftMemes

+0

Циклы и рекурсия эквивалентны. – Ani

+0

да ...давайте не будем писать Lisp в C#, если мы сможем избежать этого, используя простой цикл, пожалуйста. –

Смежные вопросы