【问题标题】:Can I use BeginInvoke with a MulticastDelegate?我可以将 BeginInvoke 与 MulticastDelegate 一起使用吗?
【发布时间】:2011-06-11 11:46:59
【问题描述】:

我想从我的库类中引发一系列事件,但我担心某些事件订阅者会很粗鲁并且需要很长时间来处理某些事件,从而阻塞引发事件的线程。我想我可以通过使用线程池线程来引发每个事件来保护引发线程:

if (packet != null && DataPacketReceived != null)
{
    var args = new DataPacketEventArgs(packet);
    DataPacketReceived.BeginInvoke(this, args, null, null);
}

当事件只有一个订阅者时,这可以正常工作,但是一旦第二个订阅者到达,DataPacketReceived 就会成为多播委托,并且我收到带有错误消息的参数异常,“委托必须只有一个目标。”有没有一种简单的方法可以在单独的线程上引发事件,还是我必须启动一个线程然后从那里引发事件?

【问题讨论】:

    标签: .net multithreading events delegates begininvoke


    【解决方案1】:

    我在another site 上发现了一个类似的问题,当然 Jon Skeet 已经回答了。对于我的场景,我选择在单独的线程上为每个订阅者引发事件:

    if (packet != null && DataPacketReceived != null)
    {
        var args = new DataPacketEventArgs(packet);
        var receivers = DataPacketReceived.GetInvocationList();
        foreach (EventHandler<DataPacketEventArgs> receiver in receivers)
        {
            receiver.BeginInvoke(this, args, null, null);
        }
    }
    

    【讨论】:

    • 正确,但请注意,对每个订阅者调用 BeginInvoke 并不一定意味着每个订阅者都将在单独的线程上运行。这是线程池的事情。
    • 在过去的几天里我一直在关注这个问题几次,重要的是要注意receivers 中的对象实际上不是EventHandler&lt;DataPacketEventArgs&gt; 类型,这是一个明确的演员表.
    猜你喜欢
    • 2011-09-09
    • 2023-03-25
    • 2020-08-04
    • 2018-10-23
    • 2011-02-22
    • 2021-03-16
    • 2016-11-20
    • 2019-01-25
    • 2017-02-20
    相关资源
    最近更新 更多