为什么EventInfo.RemoveEventHandler抛出NullReferenceException?

时间:2008-12-16 15:51:07

标签: c# .net reflection mshtml

我有一些代码使用反射在Internet Explorer BHO中的MSHTML对象上安装.NET事件处理程序,它似乎工作正常。但是,当我尝试删除事件处理程序时,我遇到了麻烦。

这就是事件处理程序安装和删除的代码:

public class HandlerExample {
    private static void Handler(IHTMLEventObj e) { ... }
    private static Delegate handlerDelegate;

    public static void InstallHandler(IHTMLElement target, string eventName)
    {
        // FindInterface() finds the correct event interface for the particular subclass of
        // IHTMLElement that target really is
        Type eventInterface = FindInterface(target);
        EventInfo eInfo = eventInterface.GetEvent(eventName);
        Type tHandler = eInfo.EventHandlerType;

        handlerDelegate = Delegate.CreateDelegate(tHandler, typeof(HandlerExample), "Handler");

        eInfo.AddEventHandler(target, handlerDelegate);
    }

    public static void RemoveHandler(IHTMLElement target, string eventName)
    {
        Type eventInterface = FindInterface(target);
        EventInfo eInfo = eventInterface.GetEvent(eventName);
        eInfo.RemoveEventHandler(target, handlerDelegate); // THIS LINE CRASHES
    }
}

InstallEventHandler的调用工作正常,然后在浏览器中触发事件时调用Handler。当我使用与RemoveEventHandler调用相同的参数调用InstallEventHandler时,最后一行会抛出TargetInvocationException,内部异常为NullReferenceException。我无法弄清楚我在这里做错了什么,堆栈跟踪没什么帮助。

编辑:我已经调试了调试器中的代码,我直接引用的对象变量都没有。

我还尝试在InstallHandler方法中同时调用AddEventHandlerRemoveEventHandler,这样可以正常工作。

堆栈跟踪如下:

System.Reflection.TargetInvocationException occurred
  Message="Exception has been thrown by the target of an invocation."
  Source="mscorlib"
  StackTrace:
       at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
       at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Reflection.EventInfo.RemoveEventHandler(Object target, Delegate handler)
       at RemoveHandler(IHTMLElement target, String eventName)
  InnerException: System.NullReferenceException
       Message="Object reference not set to an instance of an object."
       Source="Microsoft.mshtml"
       StackTrace:
            at mshtml.HTMLTextContainerEvents2_EventProvider.remove_onclick(HTMLTextContainerEvents2_onclickEventHandler )
            at mshtml.HTMLTextAreaElementClass.HTMLTextContainerEvents2_Event_remove_onclick(HTMLTextContainerEvents2_onclickEventHandler )
       InnerException: 

可能导致这种情况的原因,我该如何解决?

1 个答案:

答案 0 :(得分:0)

当你调用RemoveHandler时,看起来你的handlerDelegate是null。 我不确定为什么会发生这种情况,但您是否尝试在调用RemoveEventHandler之前实例化handlerDelegate?