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

标签 c# .net events

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

public event EventHandler Updated;

public void OnUpdated() {
    if (Updated != null) Updated(sender: this, e: null)
}

如果没有人订阅 Updated 事件,我不希望第四行造成任何显着的性能拖累(这个想法是让订阅者选择最细粒度的事件来订阅只有最少数量的事件触发并防止消息队列过载)。

我应该关心和跟踪订阅者的存在(例如使用 if (Updated != null && OnUpdateSubscribed) Updated(sender: this, e: null) 还是信任编译器/运行时?

最佳答案

检查 OnUpdate != null 定义 订阅/取消订阅的事件。事实上, bool 检查和空检查之间没有真正的区别,因为最终它们都只是一个“加载字段”,“如果为假则分支”——因为就逻辑检查而言,空引用算作“假”很关心。

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

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);
}

编译为(评论是我的):

.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 
}

关于c# - 没有监听器的事件会对性能产生相当大的影响吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11535646/

相关文章:

javascript - 如何从轮播中获取id并显示特定图像的信息?

c# - 如何限制 asp.net 中 XML 记录中显示的字符数?

c# - 有没有办法为类的特定属性隐藏一些枚举值?

c# - 无法创建对象上下文

c# - 避免在 C# winform 的键盘快捷方式上发出警报

c# - .netcore TestScheduler 的 Nuget 包

c# - 使用子查询对 Linq 进行 SQL 查询

Laravel Pusher 异常 : "Illuminate\Broadcasting\BroadcastException"

javascript - mousedown 不适用于动态加载的元素

javascript - 使用 DOM javascript 设置事件