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

C# 如何从应用程序中删除事件处理程序?,c#,C#,我已将处理程序添加到应用程序: Application.ThreadException += (sender, a) => UnhandledExceptionsHelper.ApplicationOnThreadException(a, null); 在此之后,我想添加另一个处理程序 Application.ThreadException += (sender, a) => UnhandledExceptionsHelper.ApplicationOnThreadExceptio

我已将处理程序添加到应用程序:

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]);
    }
如何对应用程序和AppDomain执行相同的操作

@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
中,它变得更加奇怪。让我们看看源代码:

看看这一行:
current.threadExceptionHandler=value

似乎只有一个处理程序,订阅会覆盖它。它没有被记录(MSDN没有对这种行为说一句话),但显然这是一个已知的问题:


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

      ThreadExceptionEventHandler handler = (sender, a) => UnhandledExceptionsHelper.ApplicationOnThreadException(a, null);
      Application.ThreadException += handler;
      //Later...
      Application.ThreadException -= handler;
      
      由于C#中的
      event
      本身只是
      add
      /
      remove
      方法的语法糖,因此没有通用的替代方法可以在不引用处理程序的情况下取消订阅事件。特别是在
      Application.ThreadException
      中,它变得更加奇怪。让我们看看源代码:

      看看这一行:
      current.threadExceptionHandler=value

      似乎只有一个处理程序,订阅会覆盖它。它没有被记录(MSDN没有对这种行为说一句话),但显然这是一个已知的问题:


      使用方法,而不是将事件与LINQ一起使用。 因此,与其这样做,不如:

      Application.ThreadException += (sender, a) => UnhandledExceptionsHelper.ApplicationOnThreadException(a, null);
      
      这样做:

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

      不要将事件与LINQ一起使用,而是使用方法。 因此,与其这样做,不如:

      Application.ThreadException += (sender, a) => UnhandledExceptionsHelper.ApplicationOnThreadException(a, null);
      
      这样做:

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

      不使用同一个处理程序就可以取消订阅吗?@SergeyBerezovskiy在一般意义上是否。事件只是一对添加/删除方法。我正在寻找ThreadException背后的原因,具体来说,可能有一个特定的解决方案。只是想知道使用相同的处理程序是否是最好的方法,哪种方法是仅次于最佳的方法?@Andrey当我尝试使用按钮时。
      -=
      。甚至单击它对我都没有帮助。我的意思是,我在移除处理程序之后第一次添加处理程序,然后再次添加处理程序。看到那个处理者开了两枪。@SergeyBerezovskiy没有第二好的。就是这样。另一种方法是编写高度不可靠的代码,通过反射进行挖掘。除非是生死攸关的情况,否则我不会这么做。不使用同一个处理程序就可以取消订阅吗?@SergeyBerezovskiy,一般意义上是否。事件只是一对添加/删除方法。我正在寻找ThreadException背后的原因,具体来说,可能有一个特定的解决方案。只是想知道使用相同的处理程序是否是最好的方法,哪种方法是仅次于最佳的方法?@Andrey当我尝试使用按钮时。
      -=
      。甚至单击它对我都没有帮助。我的意思是,我在移除处理程序之后第一次添加处理程序,然后再次添加处理程序。看到那个处理者开了两枪。@SergeyBerezovskiy没有第二好的。就是这样。另一种方法是编写高度不可靠的代码,通过反射进行挖掘。除非是生死攸关的情况,否则我不会这么做。可能重复两个问题:1)你什么时候想添加另一个处理程序?i、 e.在一些用户操作之后,或者在第一个处理程序被触发之后2)第二个处理程序的
      param
      在哪里?@Pasick这不是100%dup,因为有一些关于应用程序的细节。ThreadException@SergeyBerezovsky我在创建
      params
      之后添加了第二个处理程序。并将第一个处理程序与
      null
      一起使用,而不是
      params
      只是因为添加第一个处理程序时
      params
      不存在。两个问题可能重复:1)何时要添加另一个处理程序?i、 e.在一些用户操作之后,或者在第一个处理程序被触发之后2)第二个处理程序的
      param
      在哪里?@Pasick这不是100%dup,因为有一些关于应用程序的细节。ThreadException@SergeyBerezovsky我在创建
      params
      之后添加了第二个处理程序。并将第一个处理程序与
      null
      一起使用,而不是
      params
      只是因为添加第一个heandler时
      params
      不存在。