How to ignore the passage of time while debugger has code paused?

后端 未结 3 612
时光取名叫无心
时光取名叫无心 2020-12-20 00:39

I have calculations I\'m performing which I need to timeout if it runs too long. I might set a timeout of 5 seconds, and do periodic polls throughout my code. Actual code

3条回答
  •  臣服心动
    2020-12-20 01:11

    Ideally you would want some events to be fired when the code is paused. Since the Debugger doesn't fire an event then a workaround is needed as mentioned by Matias.

    His solution requires that you know the exact point at which you should start/stop a Stopwatch and I will build on that. The downside to this solution is that it requires constant polling at a high enough resolution for your needs (which could be detrimental to the rest of your application running thereby affecting whatever numbers you are trying to retrieve out of the timer).

    The ultimate aim is that we will do the calculation:

    "Running time paused" = "Total time taken" - "Total time paused"

    We will try to keep track of when the last time the program was actively running, and then find out when the program next actively runs after it resumes from debug.

    public static class ProgramTimer
    {
        public static int resolution = 1000; //resolution of time needed in ms
        private static System.Diagnostics.Stopwatch stopwatch;
        private static System.Timers.Timer pollingTimer;
        private static System.TimeSpan lastMeasuredDebugTimespan;
    
        public static void Start()
        {
            pollingTimer = new System.Timers.Timer();
            pollingTimer.Interval = resolution;
            pollingTimer.Elapsed += timerEvent;
        }
    
        private static void timerEvent()
        {
            if (System.Diagnostics.Debugger.IsDebuggerAttached) {
                if (stopwatch == null) {
                    stopwatch = System.Diagnostics.Stopwatch.StartNew();
                }
            } else {
                if (stopwatch != null) {
                    stopwatch.Stop();
                    lastMeasuredDebugTime = stopwatch.Elapsed.TotalMilliseconds;
                    stopwatch = null;
                }
            }
        }
    
        public static System.TimeSpan getTimespanInDebug()
        {
            if (lastMeasuredDebugTimespan) {
                return lastMeasuredDebugTimespan;
            }
            return null;
        }
    }
    

    In PrepareTimeout you would call: ProgramTimer.Start()

    And in AssertTimeout:

    public void AssertTimeout()
    {
        DateTime newEndTime;
        newEndTime = endTime; 
        if (ProgramTimer.getTimespanInDebug()) {
            newEndTime = endTime.Subtract(ProgramTimer.getTimespanInDebug());
        }
        if (DateTime.UtcNow > newEndTime)
            throw new TimeoutException();
    }
    

    Hope that helps!

提交回复
热议问题