2014-12-22 5 views
1

У меня есть два метода, и для меня нужно сгенерировать исключение из одного в другой какой-то, как этотКак бросить исключение и продолжить цикл (или как бросить много исключение из одной петли)

public void Method1() 
{ 
    try 
    { 
     Method2(1); 
    } 
    catch(Exception e) 
    { 
     SendEmail (/* some message */) 
    } 
} 

public IEnumerable<int> Method2(int id) 
{ 
    foreach (var i in col) 
    { 
     try 
     { 
      /*Do some stuff*/ 
      yield return i 
     } 
     catch 
     { 
      /* delegate this exception to Method1 and continue foreach loop */ 
     }    
    } 
} 

Как делегировать исключение из метода 2 в способе 1 и продолжить цикл по каждому элементу в методе 2

UPD:

а как насчет

, например: Метод 1 -> method3 -> Method2 -> метод 2 возврата исключение в методе 1

UPD2: к UPD

/*Call*/ 
     var i = new List<int>() {0, 0, 0, 0, 0, 0, 7, 0, 9}; 
     Calc(i, SendMessage); 


    public static void SendMessage(Exception ex) 
    { 
     Console.WriteLine(ex.ToString()); 
    } 

    public static double Calc(List<int> list, Action<Exception> callback) 
    { 
     var a = 0.00; 
     foreach (var i in list) 
     { 
      try 
      { 
       a = Calc1(i);/*if here (double)7/i it's just works but in how to include in method*/ 
      } 
      catch (Exception ex) 
      { 
       callback(ex); 
      } 
     } 
     return a; 
    } 

    public static double Calc1(int i) 
    { 
     var a = 0.00; 
     a = (double)7/i; 
     return a; 
    } 
+1

Весь смысл бросать исключение - остановить поток команд и вернуться к вызывающему абоненту. Если вы хотите отправить информацию вызывающему абоненту ** без ** остановки потока команд (т. Е. Цикла), тогда вы должны отправить событие, отправить сообщение и т. Д. – DrKoch

+3

Что бы вы ожидали, если кто-то вызвал Method2 напрямую, через Method1? –

+1

Почему бы просто не вызвать SendEmail в блоке catch в Method2 или это упрощенный пример? – Laurijssen

ответ

8
  1. У вас не может быть yield return внутри try/catch.
  2. Вы можете сделать это таким образом, если вы действительно хотите это сделать, но я действительно не рекомендую этот подход. Исключения следует обрабатывать, когда и где их бросают, или их следует перебросить на мой взгляд.

    public void Method1() 
    { 
        Method2(1, ex => SendEmail(ex)); 
    } 
    
    public IEnumerable<int> Method2(int id, Action<Exception> callback) 
    { 
        foreach (var i in new List<int>()) 
        { 
         try 
         { 
          /*Do some stuff*/ 
         } 
         catch(Exception ex) 
         { 
          callback(ex); 
         } 
    
         yield return i; 
        } 
    } 
    
    private void SendEmail(Exception ex) 
    { 
        // blah 
    } 
    
+0

Хорошо, как насчет метода 3, который вызывается методом2 и улавливает все в методе 1 – Hurricane

+0

обратный вызов метода method2 на метод3 и сделать то же самое. – kha

+0

Вы имеете в виду, что каждый метод должен иметь параметр делегирования? – AleksP

2

Вы не можете. Когда исключение возвращается к Method1, Method2 не может продолжаться.

Что вы можете сделать, однако, это дать Method2 функцию обратного вызова, которая обрабатывает исключения.

public IEnumerable<int> Method2(Func<Exception, bool> handler) 
{ 
    foreach (var item in collection) 
    { 
     try 
     { 
      // ... 
     } 
     catch (Exception ex) 
     { 
      if (!handler(ex)) 
       throw; 
     } 
    } 
} 

Теперь Method1 может передать функцию, которая получает исключение, и возвращает ли он обрабатывается, что исключение. Если это так, цикл продолжается.

1

Как отмечалось в других ответов, вы не можете «yield throw» исключение. Одним из способов было бы уловить исключение и вернуть объект, который его включает. (например, a KeyValuePair<int, Exception>)

public void Method1() 
{ 
    foreach(var i in Method2(1)) 
    { 
     if (i.Value == null) 
     { 
      // No Exception Thrown 
     } 
     else 
     { 
      // Exception Thrown 
      SendEmail(); // Send a message 
     } 
    }  
} 

public IEnumerable<KeyValuePair<int, Exception>> Method2(int id) 
{ 
    List<int> col = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
    Exception exception; 

    foreach (var i in col) 
    { 
     exception = null; 
     try 
     { 
      if ((i % 2) == 1) 
      { 
       throw new Exception("Test" + i); 
      } 
      /*Do some stuff*/ 
     } 
     catch (Exception ex) 
     { 
      exception = ex; 
     } 

     yield return new KeyValuePair<int, Exception>(i, exception); 
    } 
} 
Смежные вопросы