Add and remove event handler via reflection c# -


good day! purpose implement class allow subscribe , unsubscribe objects to(from) events. here code of class.

public static class eventsubscriber {     public static void addeventhandler(eventinfo eventinfo, object item, action action)     {         var parameters = getparameters(eventinfo);         var handler = gethandler(eventinfo, action, parameters);         eventinfo.addeventhandler(item, handler);     }      public static void removeeventhandler(eventinfo eventinfo,                         object item, action action)     {         var parameters = getparameters(eventinfo);         var handler = gethandler(eventinfo, action, parameters);         eventinfo.removeeventhandler(item, handler);     }      private static parameterexpression[] getparameters(eventinfo eventinfo)     {         return eventinfo.eventhandlertype           .getmethod("invoke")           .getparameters()           .select(parameter => expression.parameter(parameter.parametertype))           .toarray();     }      private static delegate gethandler(eventinfo eventinfo,                 action action, parameterexpression[] parameters)     {         return expression.lambda(             eventinfo.eventhandlertype,             expression.call(expression.constant(action),                       "invoke", type.emptytypes), parameters)           .compile();     } } 

as can see here 2 public methods subscribe , unsubscribe objects to(from) event. , here sample how test it

class program {     static void main()     {         test test = new test();         test.subscribetimer();         while (true)         {             if(test.a == 10)             {                 break;             }         }         test.unsubscribetimer();         while (true)         {          }     } }  class test {     system.timers.timer timer;     public int = 0;      public test()     {         timer = new system.timers.timer(1000);         timer.start();     }      public void subscribetimer()     {         var eventinfo = typeof(system.timers.timer).getevent("elapsed");         eventsubscriber.addeventhandler(eventinfo, timer, timerelapsed);         eventsubscriber.removeeventhandler(eventinfo, timer, timernotelapsed);     }      public void unsubscribetimer()     {         var eventinfo = typeof(system.timers.timer).getevent("elapsed");         eventsubscriber.addeventhandler(eventinfo, timer, timernotelapsed);         eventsubscriber.removeeventhandler(eventinfo, timer, timerelapsed);     }      public void timerelapsed()     {         console.writeline("timer elapsed");         a++;     }      public void timernotelapsed()     {         console.writeline("timer not elapsed");         a++;     } } 

the expected behaviour of sample on begining see message "timer elapsed" every second, after 10-th second should see "timer not elapsed" , do, still see "timer elapsed" too. means addeventhandler method works, removeeventhandler method doesn't.

i happy if me. in advance.

i think it's because creating new handler each time: (which doesn't match previous handler, can't removed invocation list)

public static void removeeventhandler(eventinfo eventinfo,                     object item, action action) {     var parameters = getparameters(eventinfo);     var handler = gethandler(eventinfo, action, parameters); // <--     eventinfo.removeeventhandler(item, handler); } 

why wrapping action? lose parameters? not possible add/remove eventinfo.removeeventhandler(item, action); because of parameters. if want remove newly generated handler, should return handler when want remove it.

public static delegate addeventhandler(eventinfo eventinfo, object item, action action) {     var parameters = getparameters(eventinfo);     var handler = gethandler(eventinfo, action, parameters);     eventinfo.addeventhandler(item, handler);     return handler; }  public static void removeeventhandler(eventinfo eventinfo,                     object item, delegate handler) {     eventinfo.removeeventhandler(item, handler); } 

var handler = eventsubscriber.addeventhandler(eventinfo, timer, timerelapsed);  eventsubscriber.removeeventhandler(eventinfo, timer, handler); 

Comments

Popular posts from this blog

unity3d - Rotate an object to face an opposite direction -

angular - Is it possible to get native element for formControl? -

javascript - Why jQuery Select box change event is now working? -