2017-02-13 62 views
-1

我用System.Action作爲我的代表。調用時c#委託:如何調用事件(委託)上的所有方法與潛在的例外?

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

而且別的地方

myEvent.Invoke(); 

現在的問題是,MyMethod1()將somethimes有例外。但我仍然希望MyMethod2()在此調用過程中被調用。

如何做到這一點?

關於電位異常: 這實際上是一個Unity問題,當一個方法註冊到一個事件,並且這個方法包含了gameobject的交互。當相關的MonoBehaviour被刪除時,這個方法仍然存在,但是GameObject交互會拋出異常。

+4

你不能在事件處理程序中捕獲異常嗎? –

+0

我可以,但我想在委託或事件代碼中執行此操作,因爲它在Unity中更清晰。我不想添加Unity標籤,因爲它實際上是純粹的C#問題。 – cdytoby

+1

我不知道你爲什麼認爲它「更清晰」,但它是錯誤的。我會在Luaan的回答下面。 –

回答

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 
    } 

}

編輯:我只注意到你的問題的例外部分。然後,您可以像平常一樣輕鬆地處理異常。