我对编程很新,而且我对OOP的知识有限,我决定使用事件在我的课程之间进行交流.当然,这将导致相当多的事件.
我想知道使用事件是否还有额外的开销?我假设除非事件被执行(即,类中有一个监听器根据被触发的事件执行一个函数),那么实际上应该没有太大的影响.但是我并不熟悉C#中的事件,并且想要确认是否仅仅因为触发事件而产生了大量的额外开销?
Ree*_*sey 12
我想知道使用事件是否还有额外的开销?我假设除非事件被执行(即,类中有一个监听器根据被触发的事件执行一个函数),那么实际上应该没有太大的影响.乙
一般来说,这是事实.引发事件的标准模式除了检查调用列表以查看是否存在订阅者之外什么都不做,如果没有侦听器则返回,在大多数情况下在性能方面将是非常小的,并且可能不会是一个问题.
即使有订阅者,使用事件的开销仍然相当小,因为它们通过委托调用有效地调用订阅者处理程序,这仍然相对较快(虽然比直接方法调用慢).只要你不是在非常紧密的循环中这样做,它可能是微不足道的.
话虽如此,这与任何表现问题一样,归结为衡量标准.在没有实际测量的情况下,没有办法知道实际使用情况有多重要.为了确定在您的具体情况下这是否是一个合理的设计选择,您需要分析事件的使用情况,以确保它不是一个重要问题.
D S*_*ley 10
是否有使用事件的额外开销?
嗯,是的 - 你有一个MulitcastDelegate参与,代码检查,以查看事件处理程序是否实际附加,等等.
是否只是为了解雇一个事件而产生大量的额外开销?
啊 - 真正的问题.有开销,但它有意义吗?这只能通过测量来回答.
我的猜测是,您遇到的任何开销都不会很大(否则会出现关于在性能关键应用程序中使用事件的警告,我还没有看到),并且您的应用程序还有其他部分对性能有更大影响.
万一有人在多年后偶然发现这个问题,我使用 BenchMarkDotNet 框架来测量调用事件所需的时间。我区分了 1 个订阅者和 100 个订阅者。
使用的测试代码:
private event EventHandler TestEventSingle;
private event EventHandler TestEventMultiple;
public OtherTests()
{
TestEventSingle += OtherTests_TestEvent;
for (int i = 0; i < 100; i++)
{
TestEventMultiple += OtherTests_TestEventMultiple;
}
}
private void OtherTests_TestEventMultiple(object sender, EventArgs e)
{
//Do something with the event...
}
private void OtherTests_TestEvent(object sender, EventArgs e)
{
//Do something with the event...
}
[Benchmark]
public void InvokeEvent()
{
TestEventSingle.Invoke(this, null);
}
[Benchmark]
public void InvokeEventMore()
{
TestEventMultiple.Invoke(this, null);
}
[Benchmark]
public void CallMethod()
{
OtherTests_TestEvent(this, null);
}
[Benchmark]
public void CallMethodMore()
{
for (int i = 0; i < 100; i++)
{
OtherTests_TestEventMultiple(this, null);
}
}
Run Code Online (Sandbox Code Playgroud)
检测结果:
| 方法 | 意思 | 错误 | 标准差 |
|---|---|---|---|
| 调用事件 | 1.6774 纳秒 | 0.0246 纳秒 | 0.0230 纳秒 |
| 调用事件更多 | 192.2076 纳秒 | 3.6115 纳秒 | 3.3782 纳秒 |
| 调用方法 | 0.0317 纳秒 | 0.0106 纳秒 | 0.0099 纳秒 |
| 调用方法更多 | 37.1203 纳秒 | 0.4147 纳秒 | 0.3676 纳秒 |