当调试器暂停代码时,如何忽略时间的流逝? [英] How to ignore the passage of time while debugger has code paused?

查看:109
本文介绍了当调试器暂停代码时,如何忽略时间的流逝?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在执行计算,如果计算时间过长,则需要超时。我可能将超时设置为5秒,并在整个代码中进行定期轮询。实际的代码要复杂得多,并且具有大量的递归,并且分布在许多类中,但这应该可以大致了解其工作方式。基本上,每当任何时间调用递归或执行某些可能需要花费时间的操作时,它都会调用AssertTimeout()。

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 is much more complex, and has heavy recursion and is spread over many classes, but this should give a general idea of how it works. Basically any time something calls recursion or performs something that might take time, it calls AssertTimeout().

private DateTime endTime;
public void PerpareTimeout(int timeoutMilliseconds)
{
    endTime = DateTime.UtcNow.AddMilliseconds(timeoutMilliseconds);
}

public void AssertTimeout()
{
    if (DateTime.UtcNow > endTime)
        throw new TimeoutException();
}

public void DoWork1()
{
    foreach (var item in workItems)
    {
        AssertTimeout();
        DoWork2(item)
    }
}
public void DoWork2(WorkItem item)
{
    foreach (var item in workItems)
    {
        AssertTimeout();
        // ...
    }
}

当我连接了调试器并暂停执行时,就会出现问题。我想以某种方式禁用超时时间。因此,如果它运行2秒钟,则我会遇到一个断点并等待5分钟,然后恢复运行,它将在恢复执行后再运行3秒钟再超时。

So the problem comes in when I have a debugger attached and I pause execution. I want to somehow disable the timeout for the amount of time paused. So if it runs for 2 seconds, I hit a breakpoint and wait 5 minutes, and then resume, it will run 3 more seconds after resuming execution before timing out.

I可以使用这样的内容:

I could use something like this:

public void PrepareTimeout(int timeoutMilliseconds)
{
    if (System.Diagnostics.Debugger.IsDebuggerAttached)
        endTime = DateTime.MaxValue;
    else
        endTime = DateTime.UtcNow.AddMilliseconds(timeoutMilliseconds);
}

但这基本上是在程序在调试环境中运行时提供无限超时,并且我希望它在不暂停的情况下正常超时。

But that's basically giving an infinite timeout whenever the program is running in a debug environment, and I want it to time out normally if I don't pause it.

有什么方法可以测量经过的时间而不计算调试器暂停的时间吗?

Is there any way to measure time elapsed without counting the time spent paused by the debugger?

推荐答案

看到Matias Cicero的回答后,我有了一个主意:

After seeing Matias Cicero's answer, I had an idea:

如果已连接调试器,请启动一个监视程序线程,该线程只执行睡眠操作。也许以100毫秒为增量。如果程序暂停,则对Thread.Sleep的调用将花费比预期更长的时间,并且可以通过差异增加结束时间。

If debugger is attached, start a watchdog thread which does nothing but sleep. Maybe in 100 millisecond increments. If the program becomes paused, the call to Thread.Sleep will take longer than expected, and it can increment the end time by the difference.

public class DebugWatchDog : IDisposable
{
    private bool Terminated;
    private Action<DateTime> updateEndTime;
    private DateTime endTime;
    public DebugWatchDog(Action<DateTime> updateEndTime, DateTime endTime)
    {
        if (!System.Diagnostics.Debugger.IsDebuggerAttached)
            return;
        this.updateEndTime = updateEndTime;
        this.endTime = endTime;
        updateEndTime(DateTime.MaxValue);
        var thread = new Thread(Watch);
        thread.Start();
    }
    public void Dispose()
    {
        lock (this)
            Terminated = true;
    }
    private void Watch()
    {
        DateTime priorTime = DateTime.UtcNow;
        while (true)
        {
            lock (this)
                if (Terminated)
                    return;
            Thread.Sleep(100);
            DateTime nextTime = DateTime.UtcNow;
            var diff = nextTime - priorTime;
            if (diff.TotalMilliseconds > 115)
            {
                endTime += diff;
            }
            if (DateTime.UtcNow > endTime)
            {
                updateEndTime(endTime);
                return;
            }
            priorTime = nextTime;
        }
    }
}

这篇关于当调试器暂停代码时,如何忽略时间的流逝?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆