我对编程还不是很熟悉,基于我有限的面向对象编程知识,我决定使用事件来在我的类之间进行通信。当然,这将导致相当多的事件。
我想知道使用事件是否会增加额外的开销?我认为,除非事件被执行(即,在一个类中有一个监听器根据事件触发执行函数),否则影响不会太大。但是,我并不十分了解C#中的事件,只想确认是否简单地触发事件就会产生显着的额外开销?
我对编程还不是很熟悉,基于我有限的面向对象编程知识,我决定使用事件来在我的类之间进行通信。当然,这将导致相当多的事件。
我想知道使用事件是否会增加额外的开销?我认为,除非事件被执行(即,在一个类中有一个监听器根据事件触发执行函数),否则影响不会太大。但是,我并不十分了解C#中的事件,只想确认是否简单地触发事件就会产生显着的额外开销?
如果有人在很多年后偶然发现了这个问题,我使用了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);
}
}
测试结果:
方法 | 平均值 | 误差 | 标准偏差 |
---|---|---|---|
调用事件 | 1.6774纳秒 | 0.0246纳秒 | 0.0230纳秒 |
更多调用事件 | 192.2076纳秒 | 3.6115纳秒 | 3.3782纳秒 |
调用方法 | 0.0317纳秒 | 0.0106纳秒 | 0.0099纳秒 |
更多调用方法 | 37.1203纳秒 | 0.4147纳秒 | 0.3676纳秒 |
使用事件会增加额外的开销吗?
嗯,是的 - 涉及到 MulitcastDelegate
,代码检查以查看是否实际连接了事件处理程序等。
仅触发事件会有显著的额外开销吗?
啊 - 真正的问题。有开销,但这是显著的吗?只有通过测量才能回答。我的猜测是,您遇到的任何开销都不会很大(否则会有关于在性能关键应用中使用事件的警告,但我没有见过),并且您的应用程序中有其他部分对性能影响更大。
是的,有开销。是的,它可能很显著。这也不难证明。事件是多播委托,像方法一样,委托会阻塞直到完成。
以下是比较两者执行相同工作量的实际时间:
使用事件
完成所需时间271271.687毫秒= 271.271687秒
不使用事件
完成所需时间123214.514毫秒= 123.214514秒
在最适合的情况下使用事件。