Search code examples
c#wpf

C# app actually runs faster with debugger attached


So, I have a strange problem. I'm making a WPF app that moves the mouse around. I have the following bit of code for this:

[StructLayout(LayoutKind.Sequential)]
    private struct POINT
    {
        public int X;
        public int Y;

        public static implicit operator Point(POINT point)
        {
            return new Point(point.X, point.Y);
        }
    }

    [DllImport("user32.dll")]
    private static extern bool GetCursorPos(out POINT lpPoint);

[DllImport("user32.dll", EntryPoint = "SetCursorPos")]
private static extern void SetCursorPos(int X, int Y);

private static Random random = new Random(DateTime.Now.Millisecond);

public static Point GetMousePosition()
    {
        GetCursorPos(out POINT lpPoint);
        return lpPoint;
    }

public static void MoveMouse(int x, int y, int tolerance = 10)
    {
        tolerance = Math.Max(0, tolerance);
        int startX = GetMousePosition().X;
        int startY = GetMousePosition().Y;
        int finalX = random.Next(x - tolerance, x + tolerance + 1);
        int finalY = random.Next(y - tolerance, y + tolerance + 1);
        int diffX = finalX - startX;
        int diffY = finalY - startY;
        double time = Math.Max(1, Math.Max(Math.Abs(diffX), Math.Abs(diffY)) / (5 + random.NextDouble()));
        double deltaX = diffX / time;
        double deltaY = diffY / time;
        for (int i = 1; i <= time; i++)
        {
            SetCursorPos((int)(startX + deltaX * i), (int)(startY + deltaY * i));
        }
    }

Basically long story short, call MoveMouse() with an x,y coordinate and it'll move the mouse to that point on screen ± [tolerance] pixels.

If I run it out of visual studio directly, with debugger attached, everything works as expected. However, if ran without the debugger, the mouse actually moves 2-3 times slower. I'd have to throw in a Thread.Sleep(1); inside the for loop just to match what it does in release mode. And then, if I leave the delay in there, it actually goes even slower in production! If I run the app stand-alone, observing its usual slowness, and then manually attach the debugger to it later, it suddenly becomes fast.

What gives? How can I make it go as fast in "production" as it does in debug?

To clarify: the "debug" vs "release" configuration doesn't actually make a difference. It's only different when the debugger is attached.


Solution

  • A-HA! I figured it out. On a wild hunch, I decided to dig up some time period shenanigans that I had some vague experience using a long time ago.

    I added

    [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]
    public static extern uint TimeBeginPeriod(uint uMilliseconds);
    
    [DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
    public static extern uint TimeEndPeriod(uint uMilliseconds);
    

    and then wrapped the mouse moving code in

    TimeBeginPeriod(1);
    

    and

    TimeEndPeriod(1);
    

    This normalized the speeds across all possible run modes, solving my problem. Though now I'm also left confused as to why the debugger is interfering with this stuff. :/ Oh well, for the time being I'm satisfied and that can be another adventure for another time I guess, if it ever becomes relevant again.