C# 将事件的订阅服务器作为线程池中的任务运行

C# 将事件的订阅服务器作为线程池中的任务运行,c#,event-handling,threadpool,C#,Event Handling,Threadpool,我有一个高优先级线程,它提供了一些事件来说明其操作: public event EventHandler<EventArgs> Connecting; private _MyMethod() { // ...some code OnConnecting(my_event_args); // ...more code } 我是否出错,或者这是否像直接调用订阅服务器那样,以非并行的执行顺序隐式地对所有订阅服务器

我有一个高优先级线程,它提供了一些事件来说明其操作:

    public event EventHandler<EventArgs> Connecting;
    private _MyMethod()
    { 
       // ...some code
       OnConnecting(my_event_args);
       // ...more code
    }
我是否出错,或者这是否像直接调用订阅服务器那样,以非并行的执行顺序隐式地对所有订阅服务器排序?下一个版本是将所有订阅者并行放入线程池的明智方式吗

    protected virtual void OnConnecting(EventArgs e)
    {
        foreach (var t in Connecting.GetInvocationList()) Task.Run(()=>t.DynamicInvoke(this,e));
    }

另外,我在某个地方读到,lambda的性能不如简单地调用一个委托,是否有办法摆脱它,或者建议是错误的?

事件处理程序被设计为按顺序运行,因为这就是
多播委托
的工作方式(事件本质上是
多播委托
)。因此,每个开发人员都会期待这一点。您需要明确说明,以便每个阅读代码的人都能获得非标准行为<代码>任务。Run是“发射并忘记”-你应该记住这一点(没有异常处理,任务完成时没有线索,没有取消的方法等)。性能问题不在于lambdas,而在于
DynamicInvoke
,这太慢了。听着。@dymanoid谢谢你提供的信息。虽然我不反对你所说的,但我发现完全未连接的订阅者被强制按顺序运行是令人费解的——在大多数情况下,顺序将完全不可预测。这是因为对发送方对象的可能访问吗?通过使用不同的执行上下文来解耦事件生产者和消费者是否不寻常?我的印象是,事件设施在后台有这样的想法。“通过使用不同的执行上下文来分离事件生产者和消费者是不寻常的”——不。想想“UI线程”。C#中的事件被设计为在事件引发者线程上运行——单线程。这就是为什么它们是按顺序执行的。这是设计决定。我们可以同意也可以不同意,但事情就是这样。如果需要不同的执行上下文,请自己实现。例如,有一些事件聚合器实现允许此类操作。看看我引用的答案。@Vromfondel不,你是对的。我只是想说,这样一个概念并非天方夜谭。很久以前,我还必须做一些类似的事情来确保系统的近实时属性。(好吧,这就是“他们”所说的。事实上,这只是“不要让事件处理减慢这一重要计算”)这是一项繁重的工作,但绝对不是不可能的。
    protected virtual void OnConnecting(EventArgs e)
    {
        EventHandler<EventArgs> temp = Connecting; // for thread-safety
        if (temp != null) Task.Run(() => temp(this, e));
    }
    protected virtual void OnConnecting(EventArgs e)
    {
        foreach (var t in Connecting.GetInvocationList()) Task.Run(()=>t.DynamicInvoke(this,e));
    }