C#-可重用类等待事件触发

我知道这里有点重复:Blocking and waiting for an event

但是,我在编写EventWaiter的过程中遇到了问题.这是我一直在努力的(主要)简化版本:

public class EventWaiter
{
    private AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
    private EventInfo _event = null;
    private object _eventContainer = null;

    public EventWaiter(object eventContainer, string eventName)
    {
        _eventContainer = eventContainer;
        _event = eventContainer.GetType().GetEvent(eventName);
    }
    public void WaitForEvent()
    {
        MethodInfo method = this.GetType().GetMethod("DynamicCaller");
        Delegate handler = Delegate.CreateDelegate(this._event.EventHandlerType, this, method);

        _event.AddEventHandler(_eventContainer, handler);

        _autoResetEvent.WaitOne();

        _event.RemoveEventHandler(_eventContainer, _handler);

    }
    public void DynamicCaller(/* insert magic here */)
    {
        _autoResetEvent.Set();
    }
}

用法将是:

EventWaiter ew = new EventWaiter(someClass, "someEvent");
ew.WaitForEvent();

基本上发生了什么,就是将DynamicCaller void注册为该事件的处理程序.问题是,事件具有不同的签名,并且我希望能够处理事件,而不管所使用的委托是什么.

我可以使用this._event.EventHandlerType获得委托的类型,但是无论委托是什么,如何使用它来创建完全可重用的类?如果DynamicCaller参数与事件委托参数不完全相同,则会发生异常.

作为附带说明,我做了很多研究框架中的代码的工作,如果我可以访问其中的一些代码,我认为这很容易.太糟糕了,我需要的很多类都在框架内部.

解决方法:

您应该使用表达式树来编译带有调用回调的任意参数的方法:

Expression.Lambda(
    _event.EventHandlerType,

    Expression.Call(Exrpession.Constant(_autoResetEvent), 
                    typeof(AutoResetEvent).GetMethod("Set")),

    _event.EventHandlerType.GetMethod("Invoke")
                           .GetParameters()
                           .Select(p => Expression.Parameter(p.ParameterType))
).Compile();

请注意,您可以使用泛型和表达式树使系统类型安全:

 new EventWaiter(_ => someObject.SomeEvent += _)

其中_是普通(但简短)参数名称.

上一篇:带有事件的gevent控件greenlets


下一篇:CodeGo.net>如何使只有最远的孩子收到共享事件?