Почему EventInfo.RemoveEventHandler выдает исключение NullReferenceException?

У меня есть код, который использует отражение для установки обработчиков событий .NET на объекты MSHTML в Internet Explorer BHO, и, похоже, он работает нормально. Однако у меня возникают проблемы, когда я пытаюсь удалить обработчики событий.

Вот так выглядит код для установки и удаления обработчика событий:

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. Я не могу понять, что я здесь делаю не так, да и трассировка стека не особо помогает.

РЕДАКТИРОВАТЬ: Я прошел через код в отладчике, и ни одна из переменных объекта, на которые я ссылаюсь напрямую, не имеет значения NULL.

Я также пробовал вызывать как AddEventHandler, так и RemoveEventHandler в методе InstallHandler, и это работает правильно.

След стека:

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: 

Что могло быть причиной этого и как это исправить?


person Greg    schedule 16.12.2008    source источник


Ответы (1)


Что ж, похоже, что ваш handlerDelegate имеет значение null, когда вы вызываете RemoveHandler. Я не уверен, почему это могло произойти, но пробовали ли вы создать экземпляр handlerDelegate прямо перед вызовом RemoveEventHandler?

person Victor    schedule 16.12.2008
comment
Я прошел через код в отладчике, и handlerDelegate не равен нулю, когда я вызываю RemoveEventHandler. Я обновил вопрос, чтобы отразить это. - person Greg; 17.12.2008