C# 为什么Winforms Click事件比MouseClick事件慢?

C# 为什么Winforms Click事件比MouseClick事件慢?,c#,.net,winforms,events,click,C#,.net,Winforms,Events,Click,我将按钮添加到带有循环的表单中,我注意到添加单击事件处理程序会使应用程序速度过慢。后来我尝试鼠标点击事件,而不是点击事件,它是立即工作 此屏幕截图显示了我的测试结果: 源代码: 1000个事件处理程序的结果: 点击:2892ms 鼠标点击:1ms 我不明白为什么点击事件非常慢 编辑: 如果我将构建平台目标更改为x64或任何CPU,结果将更改: 单击:5,鼠标单击:9 看起来像是x86平台目标导致了此问题,但与x86鼠标单击时间(1ms)相比,x64的结果仍然不太好 编辑2: 我改变了截图现在它会

我将按钮添加到带有循环的表单中,我注意到添加单击事件处理程序会使应用程序速度过慢。后来我尝试鼠标点击事件,而不是点击事件,它是立即工作

此屏幕截图显示了我的测试结果: 源代码:

1000个事件处理程序的结果:
点击:2892ms 鼠标点击:1ms

我不明白为什么点击事件非常慢

编辑: 如果我将构建平台目标更改为x64或任何CPU,结果将更改: 单击:5,鼠标单击:9 看起来像是x86平台目标导致了此问题,但与x86鼠标单击时间(1ms)相比,x64的结果仍然不太好

编辑2: 我改变了截图现在它会显示更好的结果

编辑3:

在测量事件处理程序附件之前,您是否尝试过先创建按钮

这里至少有两个未知数:1)按钮构造函数执行时间,2)事件处理程序订阅


更新:我试图重现问题,但两次测试的结果都是4ms-6ms。一次测试总是比较慢,还是只进行一次?有时,jitting和GCing会发生一些奇怪的事情,它们并不总是100%确定的。

虽然我不能告诉您发生了什么,但您的测试套件存在许多问题

首先,您可能应该在执行Console.WriteLine之前停止计时器,因为您现在也在测量创建WriteLine中使用的字符串所需的时间


其次,您可能希望在启动计时器之前创建按钮,因为您还需要测量按钮创建时间,包括堆栈、堆、垃圾收集和其他潜在问题。我建议将按钮分配到一个数组,然后在启动秒表后为项目分配偶数处理程序。

我不确定,因为我只有一个小4ms用于ClickTest()。然而,我已经将代码更改为这个,4ms的时间已经过去了

EventHandler d = new EventHandler(Form1_Click);
for (int i = 0; i < buttons.Length; i++) buttons[i].Click += d;
EventHandler d=新的EventHandler(Form1\u单击);
对于(int i=0;i

您编写的循环中的代码相当于
按钮[i]。单击+=neweventhander(Form_Click)
,它会在每次迭代中创建新的委托实例。

i repo,但它特定于VS2010。在VS2008中没有这样的行为,两者都在不到1个刻度内执行。它也不依赖于.NET版本

这看起来像是IntelliTrace中的一个缺陷,在最终版本中可用。尝试深入挖掘并启用非托管代码调试可以消除这种影响。项目+属性,调试选项卡,勾选“启用非托管代码调试”。另外,在不使用调试器的情况下运行程序(Ctrl+F5)会消除该效果。扣篮是工具+选项、IntelliTrace、General、untick启用来移除效果

我建议您将调查结果发布到connect.microsoft.com。您可以在反馈报告中引用此线程。他们需要知道的诊断问题的一切都是可用的


如前所述,解决方法是禁用IntelliTrace。这保证不会在您客户的机器上出现问题。

我能够复制他的结果。在我的实际项目中,我先创建了按钮,然后只单击事件处理程序订阅,速度非常慢。它每次都给出相同的结果。现在,我尝试构建x64,结果非常有趣:单击:3鼠标单击:25看起来像是x84构建在我的w7 64位操作系统中导致了这个问题。
elapsedmillesons
将在任何控制台事件发生之前被调用。@Mystere Man:你到底在说什么字符串创建?传递给WriteLine的任何对象只会在WriteLine内部进行字符串化,而不是在WriteLine之前。在WriteLine函数调用之前调用连接运算符,因此它不会在WriteLine中进行字符串化,而是在WriteLine之前进行。@Mystere Man:ElapsedMilliseconds的计算也会在字符串连接之前进行(很抱歉,我之前错过了这一点)。字符串常量的加载可能发生在以前,但我认为这不会有多大影响。关键是操作发生在实际处理完成之后,最好停止计时器,这样就不会在无关例程(例如GC)中消耗任何额外的时间。这解决了我在x64版本上的问题,现在是0毫秒,但在x86版本上没有任何变化,它仍然是2900毫秒。您的版本平台是什么?因为这个问题只发生在版本平台是x64时。需要64位操作系统进行测试。我忘了提到4毫秒的时间只发生在我的机器上的x86版本上。x64和任何APU版本的结果总是相同的0ms。我正在运行Windows 7 x64、Visual Studio 2008和.Net Framework 3.5 SP1。在每次结果为0ms时立即禁用IntelliTrace后。感谢帮助。我将在connect.microsoft.com上发布错误报告