2017-02-21 181 views
1

我加入處理程序申請:如何從應用程序中刪除事件處理程序?

Application.ThreadException += (sender, a) => UnhandledExceptionsHelper.ApplicationOnThreadException(a, null); 

這個我想添加另一個處理程序

Application.ThreadException += (sender, a) => UnhandledExceptionsHelper.ApplicationOnThreadException(a, param); 

如何刪除以前的處理程序之後?

當我刪除控制處理程序,我只是用:

public void RemoveOnThreadException(SimpleButton b) 
    { 
     FieldInfo f1 = typeof(Control).GetField("EventClick", 
      BindingFlags.Static | BindingFlags.NonPublic); 
     object obj = f1.GetValue(b); 
     PropertyInfo pi = b.GetType().GetProperty("Events", 
      BindingFlags.NonPublic | BindingFlags.Instance); 
     EventHandlerList list = (EventHandlerList)pi.GetValue(b, null); 
     list.RemoveHandler(obj, list[obj]); 
    } 

我怎樣才能做同樣的應用程序和應用程序域?

@Andrey有我嘗試用Button.Click:

public TestForm() 
{ 
    InitializeComponent(); 
    simpleButton1.Click += (sender, a) => simpleButton1_Click(sender,a); 
    simpleButton1.Click -= simpleButton1_Click; 
    simpleButton1.Click += (sender, a) => simpleButton1_Click(sender, a); 
} 

private void simpleButton1_Click(object sender, EventArgs e) 
{ 
    MessageBox.Show("Hi"); 
} 

,當我點擊按鈕,我得到兩個消息。

+3

[C#中取消匿名方法(可能的重複http://stackoverflow.com/questions/183367/unsubscribe-anonymous-方法在C - 尖銳) – Pasick

+0

兩個問題:1)當你想添加另一個處理程序?即在一些用戶操作之後,或者在第一個處理程序被觸發後2)你在哪裏得到第二個處理程序的'param'? –

+0

@Pasick這不是100%重複,因爲有一些關於Application.ThreadException的具體細節 – Andrey

回答

5

刪除的處理程序,最好的辦法是使用相同的處理器退訂:

ThreadExceptionEventHandler handler = (sender, a) => UnhandledExceptionsHelper.ApplicationOnThreadException(a, null); 
Application.ThreadException += handler; 
//Later... 
Application.ThreadException -= handler; 

由於event本身在C#只是爲add/remove方法的語法糖,還有來自退訂沒有通用的替代方法沒有引用處理程序的事件。尤其是Application.ThreadException它甚至變得更加怪異。讓我們來看看源代碼:

https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Application.cs,8243b844777a16c3,references

public static event ThreadExceptionEventHandler ThreadException { 
    add { 
     Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "AffectThreadBehavior Demanded"); 
     IntSecurity.AffectThreadBehavior.Demand(); 

     ThreadContext current = ThreadContext.FromCurrent(); 
     lock(current) {      
      current.threadExceptionHandler = value; 
     } 
    } 
    remove { 
     ThreadContext current = ThreadContext.FromCurrent(); 
     lock(current) { 
      current.threadExceptionHandler -= value; 
     } 
    } 
} 

看看這一行:current.threadExceptionHandler = value;

似乎只能有一個處理程序,訂閱覆蓋它。它不記錄(MSDN不說一個有關此問題的話),但顯然它是已知問題:

+0

是否可以取消訂閱而不使用相同的處理程序? –

+0

@SergeyBerezovskiy在一般意義上沒有。事件只是一對添加/刪除方法。我正在查看ThreadException的具體內容,可以有一個特定的解決方案。 – Andrey

+0

只是想知道如果使用相同的處理程序是最好的方式,哪種方式是最好的方式? –

0

而不是使用LINQ的,使用活動方法。的 所以不是這樣:

Application.ThreadException += (sender, a) => UnhandledExceptionsHelper.ApplicationOnThreadException(a, null); 

這樣做:

Application.ThreadException += MyThreadExceptionHandler; 

.... 

public void MyThreadExceptionHandler(object sender, object a) 
{ 
    //your error handling code 
} 
相關問題