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
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!