2017-02-13 38 views
-1

Я использую System.Action как мой делегат.C# Delegate: Как вызвать ВСЕ методы для события (делегата) с потенциальным исключением?

public event Action myEvent; 
myEvent+=MyMethod1; 
myEvent+=MyMethod2; 

И где-то еще

myEvent.Invoke(); 

Теперь проблема, MyMethod1() воли somethimes есть исключение при вызове. Но я все равно хочу, чтобы во время этого вызова вызывались MyMethod2().

Как это сделать?

О потенциальном исключении: Это действительно проблема Единства, когда метод зарегистрирован для события, и этот метод содержит взаимодействие с игровым объектом. Когда связанный MonoBehaviour удален, этот метод все еще существует, но взаимодействие с игровым объектом будет вызывать исключение.

+4

Не можете ли вы избежать исключения в обработчиках событий? –

+0

Я могу, но я хочу сделать это в коде делегата или события, потому что он более ясен в Unity. И я не хочу добавлять тег Unity, потому что это действительно чистый вопрос C#. – cdytoby

+1

Я не знаю, почему вы думаете, что это «более ясно», но это неправильно. Я бы пошел с ответом Луаана ниже. –

ответ

2

Вместо myEvent.Invoke, вы можете использовать GetInvocationList:

foreach(var dele in myEvent.GetInvocationList()) 
    { 
     try 
     { 
      dele.DynamicInvoke(); 
     } 
     catch(Exception e) 
     { 
      //If possible, change the above type to be more specific 
      //Also, do *something* here - at least log it somewhere 
      //Empty catch blocks are evil to debug and reason about 
     } 
    } 

Выше одна идея - вы можете сделать это немного по-другому, если вам, например, хотите удалить делегатов, которые бросают.

+0

DynamicInvoke удобен, но также немного медленнее. Просто отметим, что его можно заменить. –

4

Это одна из тех сложных вещей. Обработчики событий не должны возвращать значения. Это включает в себя исключение, если вы хотите, чтобы вещи были достаточно детерминированными. Что может сделать обработчик-обработчик действительно для того, чтобы выбрасывалось исключение?

Но ваш пример очень ясно показывает, что ваша проблема в самом обработчике - исправьте обработчик. Это не должно бросать исключения только потому, что игровой объект больше не существует! Вы также должны убедиться, что все обработчики должным образом удалены из события в соответствующее время. Похоже, что ваши обработчики сохраняются в случае, если они уже давно удалены.

0

Лучшим дизайном будет вызов одного метода, и в рамках этого метода вызовите два метода, которые необходимо вызвать, поскольку это увеличит cohesion.

myEvent+=myEvent_handler 

void myEvent_handler() 
{ 
    try 
    { 
    MyMethod1(); 
    } 
    catch (Exception ex) 
    { 
    //handle it 
    } 
    try 
    { 
    MyMethod2(); 
    } 
    catch (Exception ex) 
    { 
    //handle it 
    } 

}

EDIT: Я просто заметил, что исключения часть вашего вопроса. Вы можете обрабатывать исключения легко, как обычно.