如何从应用程序中删除事件处理程序



i被添加到应用程序中:

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有我的尝试。单击:

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

当我单击按钮时,我收到了两条消息。

删除处理程序的最佳方法是使用同一处理程序取消订阅:

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

由于C#中的event本身只是add/remove方法的语法糖,因此没有一般的替代方法可以在没有参考处理程序的情况下取消订阅事件。特别是使用Application.ThreadException,它甚至变得更奇怪。让我们看一下源代码:

https://referencesource.microsoft.com/#system.windows.forms/winforms/managed/managed/system/winforms/application.cs ,,8243b844777a16c3,refences

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没有对此行为说一句话),但显然是已知的问题:

  • https://www.simple-talk.com/blogs/theres-only-only-one-threadexceptionhandler/
  • 只能有1个和1个用于ThreadException的处理程序?

,而不是使用linq的事件,使用方法。因此,而不是这样做:

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

这样做:

Application.ThreadException += MyThreadExceptionHandler;
 ....
public void MyThreadExceptionHandler(object sender, object a)
{
    //your error handling code
}

最新更新