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
Post a Comment