Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 没有侦听器的事件会对性能产生相当大的影响吗?_C#_.net_Events - Fatal编程技术网

C# 没有侦听器的事件会对性能产生相当大的影响吗?

C# 没有侦听器的事件会对性能产生相当大的影响吗?,c#,.net,events,C#,.net,Events,考虑到类中与事件相关的以下基本代码: public event EventHandler Updated; public void OnUpdated() { if (Updated != null) Updated(sender: this, e: null) } 如果没有人订阅更新的事件,我不希望第四行造成任何显著的性能拖累(其想法是让订阅者选择最细粒度的事件进行订阅,以仅触发最少数量的事件,并防止消息队列过载) 我是否应该关注并跟踪订阅者的存在(例如,如果(已更新!=null&

考虑到类中与事件相关的以下基本代码:

public event EventHandler Updated;

public void OnUpdated() {
    if (Updated != null) Updated(sender: this, e: null)
}
如果没有人订阅更新的事件,我不希望第四行造成任何显著的性能拖累(其想法是让订阅者选择最细粒度的事件进行订阅,以仅触发最少数量的事件,并防止消息队列过载)


我是否应该关注并跟踪订阅者的存在(例如,如果(已更新!=null&&OnUpdateSubscribed)已更新(发送者:this,e:null)或信任编译器/运行时?

检查
OnUpdate!=null
定义了订阅/取消订阅的事件。事实上,布尔检查和null检查之间没有真正的区别,因为它们最终都只是一个“加载字段”,“如果为false,则进行分支”-因为null引用计数为“false”就逻辑检查而言

我唯一的建议是:将其存储在局部变量中,以防止(不太可能,但可能)竞争条件:

var snapshot = Updated;
if(snapshot != null) snapshot(this, EventArgs.Empty);
所以:不,基本上:这没有开销

例如:

public event EventHandler SomeEvent;
protected virtual void OnSomeEvent()
{
    var snapshot = SomeEvent;
    if (snapshot != null) snapshot(this, EventArgs.Empty);
}
汇编至(我的评论):


谢谢,您能确认以下扩展阻止这种竞争条件吗?:publicstaticvoidraise(这个EventHandler处理程序,objectsender,EventArgs args){if(handler!=null)处理程序(sender,args);}@ErwinMayer应该也可以,而且:没有显著的开销(特别是静态调用之后)。它确实会增加一些额外的“负载”,但是:没有什么值得兴奋的。在所有可能导致性能下降的因素中,我会把它放在(很长)的底部附近,list.我想不出任何真正的应用程序会对整体性能产生显著影响。正如Marc所说,你对此无能为力。我说的是一个应用程序,否则每秒会触发数千个事件,这就是为什么它可以加起来。。。
.method family hidebysig newslot virtual instance void OnSomeEvent() cil managed
{
    .maxstack 3
    .locals init (
        [0] class [mscorlib]System.EventHandler snapshot)

    // var snapshot = SomeEvent
    L_0000: ldarg.0 
    L_0001: ldfld class [mscorlib]System.EventHandler Foo::SomeEvent
    L_0006: stloc.0

    // if(snapshot == null) goto L_0016;
    L_0007: ldloc.0 
    L_0008: brfalse.s L_0016

    // snapshot(this, EventArgs.Empty);
    L_000a: ldloc.0 
    L_000b: ldarg.0 
    L_000c: ldsfld class [mscorlib]System.EventArgs [mscorlib]System.EventArgs::Empty
    L_0011: callvirt instance void [mscorlib]System.EventHandler::Invoke(object, class [mscorlib]System.EventArgs)

    // L_0016: return;
    L_0016: ret 
}