page 1 of 1
Comments: 12 | Views: 2144
joshnuss
joshnuss
Joshua Nussbaum
Ever wondered how much time you spend waiting for Visual Studio to respond?
Well its been driving me nuts for a while so I wrote a little app to tracks the time that VS 2008 spends "not responding".
I think you'll be shocked by the results on solutions with 15+ projects.

Hopefully making this information available to others will motivate Microsoft to fix these problems.

Heres the code for your enjoyment (tested with VS 2008)..

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace CalulateHangTime
{
[Flags]
public enum SendMessageTimeoutFlags : uint
{
SMTO_NORMAL = 0x0000,
SMTO_BLOCK = 0x0001,
SMTO_ABORTIFHUNG = 0x0002,
SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
}

public static class ExternalMethods
{
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg,
UIntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags,
uint uTimeout, out UIntPtr lpdwResult);
}

class Program
{
static readonly uint WAIT_MILLISECONDS = 2;
static readonly int SLEEP_MILLISECONDS = 1000;

static void Main(string[] args)
{
long seconds = 0;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
while (true)
{
IntPtr hWnd = ExternalMethods.FindWindow("wndclass_desked_gsk", null);
if (hWnd == IntPtr.Zero)
throw new InvalidOperationException("Handle to window could not be found");


UIntPtr result;
IntPtr success = ExternalMethods.SendMessageTimeout(hWnd, 0, UIntPtr.Zero, IntPtr.Zero,
SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, WAIT_MILLISECONDS, out result);

if (success == IntPtr.Zero)
{
seconds += SLEEP_MILLISECONDS / 1000;

Console.WriteLine("Visual Studio is hung. {0}/{1} seconds wasted", seconds, stopWatch.Elapsed.TotalSeconds);
}
else
{
Console.WriteLine("Visual Studio is running fine.");
}

Thread.Sleep(SLEEP_MILLISECONDS);
}
}
}
}

jh71283
jh71283
Throw new System.Beverage. OutOfCoffeeException​()

<Rant>
The part that I find most irritating, is the fact the compilation hangs the GUI!

If you have a fairly large project, then compiling takes time, we accept that.

But why does it hand the gui? It is being done on a sperate thread, which we can tell by the fact that *sometimes* it is possible to cancel the build from the build menu.

I just don't think they've spend much time on the threading when it comes to building the project, and so there are thousands of developer hours wasted by this silly scenario



</Rant>
littleguru
littleguru
allein, allein,... allein, allein!
Heh. Interesting project. Although I never experience the problems, might be that my projects are to small perhaps.
Funny and nicely done. Good job cheers
Joshua,

I just saw your post and looked at your code.  It's an interesting way to measure performance, but I think you're unfairly assuming that any non-success code is due to a hang situation; however, it could also be due to a timeout, which you've set to only 2ms.

So what's happening is this - every second you take the pulse of VS, and if at that particular instant in time, it's doing anything that takes longer than 2 ms, then you're counting the entire second as being hung.  I don't think that's really fair.

As a general rule of thumb, I tell people that it's okay to hang the UI thread for up to 100 ms during typing (although I prefer they keep it to under 50ms) and up to 4000 ms when displaying a dialog box (although I prefer they keep it well under 2000 ms).

Of course, I'm not saying that VS doesn't have some performance issues that we need to address, just that I don't think they're as bad as your program implies.

If you'd like to discuss the issue further, you can e-mail me at DevPerf@Microsoft.com.

Regards,

David Berg
Microsoft Developer Division
Performance Engineering Team

jh71283,

Yes, it's unfortunate that compilation hangs the UI.  We need to fix it.  For what it's worth, it's  a multi-stage process, and most of it is (unfortunately) done on the UI thread, which is why it hangs and why the cancel button doesn't work.

The time when it does work is only one small part of the overall process that actually checks...

Again, as I said, we need to fix it (and everything else like it).

Regards,

David Berg
Microsoft Developer Division
Performance Engineering Team

jh71283
jh71283
Throw new System.Beverage. OutOfCoffeeException​()
Oh well, at least you guys are aware and working on it...

I does beg the queston though why the decision was made to compile on the ui thread though... oh well!
As pointed out, that's not a very fair measurement.

I do know however, that I've wasted a *lot* of time by accidentally pressing "Rebuild Solution" instead of "Build Solution" in the build menu. "Rebuild Solution" really, really needs a "Yes/No are you sure" prompt
figuerres
figuerres
???
David Berg wrote:


jh71283,

Yes, it's unfortunate that compilation hangs the UI.  We need to fix it.  For what it's worth, it's  a multi-stage process, and most of it is (unfortunately) done on the UI thread, which is why it hangs and why the cancel button doesn't work.

The time when it does work is only one small part of the overall process that actually checks...

Again, as I said, we need to fix it (and everything else like it).

Regards,

David Berg
Microsoft Developer Division
Performance Engineering Team



Hey, thanks for posting and showing that someone @ msft saw the post etc...

most of the time I *LOVE* using VS but there are some places where it could use some love Smiley

BTW:  on Vista I *HATE* it when the "Help update" locks up things.
also the "White Screen" stage when someting has stolen the UI thread or whatever it is doing behind the curtain....
does not happen real often but sure makes it *LOOK* like it crashed and has frozen... needs a dialog to say "VS 200x Pro is busy, Please wait..." to tell the dev it is busy and not totaly crashed.


andur wrote:
As pointed out, that's not a very fair measurement.

I do know however, that I've wasted a *lot* of time by accidentally pressing "Rebuild Solution" instead of "Build Solution" in the build menu. "Rebuild Solution" really, really needs a "Yes/No are you sure" prompt


No it doesn't. I can't think of anything worse than constantly being asked if I really want to rebuild when that's what I actually want to do. What would help though is not having the two options right next to each other. Try rearranging the menu options and see if that works better for you.
AndyD wrote:

andur wrote:As pointed out, that's not a very fair measurement.

I do know however, that I've wasted a *lot* of time by accidentally pressing "Rebuild Solution" instead of "Build Solution" in the build menu. "Rebuild Solution" really, really needs a "Yes/No are you sure" prompt


No it doesn't. I can't think of anything worse than constantly being asked if I really want to rebuild when that's what I actually want to do. What would help though is not having the two options right next to each other. Try rearranging the menu options and see if that works better for you.


It's always interesting to see comments like this. One feature that is a waste to someone else (for whatever reason) it a vital tool to someone else. Changes based on one person/groups perspectives is never a good thing, especially when it's something that you can work around already.


As for the topic, along with counting potentially 998 extra milliseconds for each non-responsive event or even 1000 milliseconds for any non-success condition, the original test code counts not only the sleeping (1 second) but execution of the code for the total seconds. Since there is some marshaling done in it, it's not guaranteed to be quick, though in you're worst case event (waiting 2 milliseconds). Your count would be skewed because the stopwatch will count for at least 1002 milliseconds for ever 1 seconds you add to the "wasted time". That's ignoring the fact that Thread.Sleep(1000) is only a guarantee that it will sleep for at least 1000 milliseconds not that it will wake up in exactly 1000 milliseconds. It could be delayed even longer if a higher priority thread preempts it even after it returns to the ready state. Note that these things may actually skew the analysis to be lower than what it really is. However it still means the "analysis" is faulty.

It should have been developed as the Tick/TimeElapsed event of one of the timers rather than a loop with Thread.Sleep. Or some other method of timing that is more accurate than relying on the Sleep method should have been used.

Peter Richie had a blog post about Thread.Sleep and why it is useless for keeping time and other abuses of it.

This is in addition to changes that would be needed to reconcile adding one whole second for any reason for the failed call.
kurt_godel
kurt_godel
Trashed me!
Nice project Joshua.

I have not used VS2008 yet but my VS2005 has such kind of problems (not with compiling but with starting/ending time)
I never understood while loading (even to the blank project) or unloading should take so much time. I have set it not to load any project but still it takes me 10-15 secs to launch it.

In comparison, Netbeans is terrible in the loading phase but closes very fast. Anyway, VS is still the best.