2017-02-21 39 views
1

ich Handler Anwendung hinzugefügt:Wie Ereignishandler aus der Anwendung entfernen?

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

Danach i Wie andere Handler

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

hinzufügen möchten, kann ich vorherige Handler entfernen?

Wenn i-Handler von Control löschen benutze ich nur:

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]); 
    } 

Wie kann ich das gleiche tun mit Anwendung und AppDomain?

@Andrey gibt es meine Versuche mit 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"); 
} 

Und wenn i-Taste klicken bekam ich zwei Nachrichten.

+3

Mögliche Duplikat [Abmelden anonyme Methode in C#] (http://stackoverflow.com/questions/183367/unsubscribe-anonymous- method-in-c-sharp) – Pasick

+0

Zwei Fragen: 1) Wenn Sie einen anderen Handler hinzufügen möchten? d. h. nach einer Benutzeraktion oder nachdem der erste Handler abgefeuert wurde 2) wo Sie "param" für den zweiten Handler erhalten? –

+0

@Pasick das ist nicht 100% dup, weil es einige Besonderheiten in Bezug auf Application.ThreadException gibt – Andrey

Antwort

5

Der beste Weg, den Handler zu entfernen, ist die gleichen Handler abzumelden mit:

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

Da event selbst in C# für add/remove Methoden nur Syntax Zucker ist, gibt es keine allgemeine alternative Art und Weise von abzumelden ist ein Ereignis ohne einen Verweis auf einen Handler. Speziell mit Application.ThreadException wird es noch seltsamer. Schauen wir uns den Quellcode aussehen:

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; 
     } 
    } 
} 

Blick auf diese besondere Linie: current.threadExceptionHandler = value;

es, dass es scheint nur ein Handler sein kann, und abonnieren außer Kraft gesetzt. Es ist nicht dokumentiert (MSDN sagt kein Wort über dieses Verhalten), aber anscheinend ist es bekannt, Ausgabe:

+0

Kann ich mich abmelden OHNE den gleichen Handler zu verwenden? –

+0

@SergeyBerezovskiy im allgemeinen Sinn nicht. Event ist nur ein Paar Add/Remove-Methoden.Ich schaue mir gerade an, was hinter ThreadException steckt, es kann eine bestimmte Lösung geben. – Andrey

+0

Frage mich nur, ob die Verwendung des gleichen Handlers der beste Weg ist, welcher Weg ist der zweitbeste? –

0

Anstatt die Events mit LINQ, Verwendung Methoden. Statt dies zu tun:

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

tun:

Application.ThreadException += MyThreadExceptionHandler; 

.... 

public void MyThreadExceptionHandler(object sender, object a) 
{ 
    //your error handling code 
} 
Verwandte Themen