views:

152

answers:

4

I'm adding buttons to form with loop and i noticed adding click event handlers slowing down application too much. Later i tried mouse click event instead click event and it is working instantly.

This screenshot showing my test result: alt text Source code: http://pastebin.com/qVewNm1u

Results for 1000 event handler:
Click: 2892ms MouseClick: 1ms

I can't figure out why Click event very slow.

Edit: If i change build platform target to x64 or Any CPU, results changing: Click: 5, MouseClick: 9 Look like x86 platform target causing this problem but still x64 results not good too compared to x86 MouseClick time (1ms).

Edit2: I changed screenshot now it will show better result.

Edit3: https://connect.microsoft.com/VisualStudio/feedback/details/597039/winforms-click-event-slower-than-the-mouseclick-event

A: 

Have you tried creating the buttons first, before measuring the event handler attachment?

There are at least two unknowns here: 1) the button constructor execution time, and 2) the event handler subscription.

Update: I tried to reproduce the problem but I consistently get 4ms-6ms for both tests. Is the one test always slower, or did it happen just once? Sometimes weird things happen with jitting and GCing that aren't always 100% deterministic.

Charlie Salts
I was able to duplicate his results. I'll get 4000+ ms for the first and 1ms for the second.
Robaticus
In my real project i created buttons first and only click event handler subscription very slow. It is giving every time same results. Now i tried to build x64 and results very interesting: Click: 3MouseClick: 25Look like x84 build causing this problem in my w7 64bit os.
Jaex
A: 

While I can't tell you what's going on, there are a number of problems with your test suite.

First, you should probably stop the timer before doing the Console.WriteLine, since you are now also measuring how long it takes to create the string used in the WriteLine.

Second, you may want to create the buttons before starting the timer, because you're also measuring the button creation time, which includes stack, heap, garbage collection, and other potential issues. I'd suggest allocating the buttons to an array, then assigning the even handlers to the items after you start the stopwatch.

Mystere Man
`ElapsedMilliseconds` will be called before any Console stuff happens.
leppie
I didn't say it did. Reread what I said.
Mystere Man
Same result: http://img841.imageshack.us/img841/9932/ss20100911064602.png
Jaex
@Mystere Man: Exactly what string creation are you talking about? Any object passed to WriteLine will only be stringified inside WriteLine, not before.
leppie
The concatenation operator is called before the writeline function call, so it's not stringified in WriteLine, but before it.
Mystere Man
@Mystere Man: The evaluation of `ElapsedMilliseconds` will happen before the string concatenation too (sorry I missed that earlier). The loading of a string constant might happen before, but I cant think that would matter much.
leppie
The point is that operations occur after the actual processing is done, it's better to stop your timer so that any additional time is not consumed in extraneous routines (GC for instance).
Mystere Man
A: 

I am not sure because I have only a small 4ms for ClickTest(). However, I have change the code to this and the 4ms time is gone.

EventHandler d = new EventHandler(Form1_Click);
for (int i = 0; i < buttons.Length; i++) buttons[i].Click += d;

The code in the loop you wrote are equivalent to button[i].Click += new EventHander(Form_Click), which create new delegate instance on every iteration.

tia
This solve my problem for x64 build, now it is 0ms but nothing changed for x86 build it is still 2900ms. What is your build platform? Because this problem only happens when build platform is x64. Need 64bit OS for test.
Jaex
I forgot to mention that the 4ms time occurred only on x86 build on my machine. The result from x64 and Any APU build are always 0ms. I am running Windows 7 x64, Visual Studio 2008 and.Net Framework 3.5 SP1.
tia
+2  A: 

I repro, but it is specific to VS2010. There is no such behavior in VS2008, both execute in less than 1 tick. It also doesn't depend on the .NET version.

This looks like a defect in IntelliTrace, available in the Ultimate edition. Trying to dig deeper and turning unmanaged code debugging on removed the effect. Project + Properties, Debug tab, tick "Enable unmanaged code debugging". Also, running the program without the debugger (Ctrl+F5) removed the effect. The slam-dunk is Tools + Options, IntelliTrace, General, untick Enable to remove the effect.

I recommend you post your findings to connect.microsoft.com. You can reference this thread in your feedback report. Everything they need to know to diagnose the problem is available.

As noted, the workaround is to disable IntelliTrace. This is guaranteed to not be a problem on your customer's machine.

Hans Passant
After disable IntelliTrace now every time results 0ms. Thanks for help. I will post bug report in connect.microsoft.com
Jaex
Excellent detective work, Hans!
Robaticus