使用EventHandlerList多次订阅一个事件

时间:2011-05-08 20:55:14

标签: c# events sync

目标:我想多次订阅不同课程中的同一个活动。我有以下课程:

public class MyEngine : IEngine
{
    private EventHandlerList _events = new EventHandlerList();

    protected EventHandlerList Events
    {
        get
        {
            return _events;
        }
    }

    private readonly string OnReceivedEventName = "OnReceived";

    public event MessageEventHandler OnReceived
    {
        add
        {
            lock (this)
            {
                Events.AddHandler(OnReceivedEventName, value);
            }
        }
        remove
        {
            lock (this)
            {
                Events.RemoveHandler(OnReceivedEventName, value);
            }
        }
    }

    protected internal virtual void MessageReceived(MessageEventArgs e)
    {

        var handler = Events[OnReceivedEventName] as MessageEventHandler;
        TryFireMessageEvent(handler, e);
    }

    private void TryFireMessageEvent(MessageEventHandler handler, MessageEventArgs e)
    {
        try
        {
            if (handler != null)
                handler.Invoke(this, e);
        }
        catch (Exception ex)
        {
            log.Error("Message Received - Exception caught", ex);
            ErrorOccurred(ex);
        }
    }
}

主模块有一个IEngine实例:

public class MyProvider
{
    protected internal IEngine Engine { get; set; }
    public MyProvider(IEngine engine)
    {
        Engine = engine;
        engine.OnReceived += Engine_Received;
    }
    protected internal void Engine_Received(IEngine engine, MessageEventArgs args)
    {...}
}

我还有一个函数'DoAction'来创建一个操作并注入引擎:

public class MyProvider
{
    ....
    public Result DoAction()
    {
        using (var operation = new SyncOperation(Engine))
        {
            operationResult = operation.Execute();
        }
    }
}

SyncOperation:

public class SyncOperation : IDisposable
{
    private IEngine _engine;

    public SyncOperation (IEngine engine)
    {
        Ensure.NotNull(engine, "engine");
        _engine = engine;

        _engine.OnReceived += Engine_OnReceived;
    }

    internal void Engine_OnReceived(IEngine engine, MessageEventArgs args)
    {...}
}

调用operation.Execute();并非所有收到的事件都在SyncOperation类中引发。

我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

我将您的代码与一个已知良好的示例进行了比较,我怀疑private readonly string OnReceivedEventName是否为对象密钥。你在这里依赖字符串实习,'normal'是一个静态对象。

这让我想知道正常生成的事件是否是线程安全的。无法如此快速地找到参考,但作为诊断:

public event MessageEventHandler OnReceived;

可能当时有竞争条件,但这种情况非常罕见(并且很容易最小化/消除)。所有的处理程序都被调用了吗?