最初,我假设是的,因为我知道多播委托的调用列表是作为链表实现的,它支持恒定时间的插入和删除。然而,由于多播委托是不可变的,似乎任何添加/删除操作实际上都需要复制调用列表。这是正确的,还是我错过了什么?
注册/注销的成本很有趣,因为我有一个长期运行的应用程序,它经常将各种短期对象的处理程序注册到事件中,然后在它们被释放之前注销它们。调用列表可能会变得相当长,所以我真的希望这是一个恒定时间操作。
最初,我假设是的,因为我知道多播委托的调用列表是作为链表实现的,它支持恒定时间的插入和删除。然而,由于多播委托是不可变的,似乎任何添加/删除操作实际上都需要复制调用列表。这是正确的,还是我错过了什么?
注册/注销的成本很有趣,因为我有一个长期运行的应用程序,它经常将各种短期对象的处理程序注册到事件中,然后在它们被释放之前注销它们。调用列表可能会变得相当长,所以我真的希望这是一个恒定时间操作。
调用列表可能会变得相当长,所以我真的希望这是一个恒定时间操作。
“相当”多长?除非您谈论的是成千上万的订阅者,否则这不太可能是一个重要的时期。
启动一个测试项目并试一试——实际测量胜过任何数量的聪明的老人(或女人)。
更新
一个想法:如果您的具体情况是处理对象时,请尝试以下操作:
public event PropertyChanged
{
add { mPropertyChanged += value; }
remove { mPropertyChanged -= value; }
}
public void Dispose()
{
mPropertyChanged = null;
}
在您的Dispose方法中,您只需删除对存储事件的引用即可一次性丢弃所有订阅。这无疑比一个一个退订要快。
是的,您将多播委托放弃给垃圾收集器,但是当您取消订阅时,无论如何您都在这样做 - 事实上,每次取消订阅一次。
根据 Has Passant 评论 2011 年 8 月 22 日 21:31
添加是摊销 O(1),与 List<>.Add() 完全相同的逻辑。删除是 O(n)。你无法改变这一点。