debugging C#事件在调用blog.Break()之前和之后?

jogvjijk  于 8个月前  发布在  C#
关注(0)|答案(3)|浏览(68)

我正在调试一个人工智能机器人,它被输入“重放”输入数据,让它重放以前玩过的比赛。每个回合都有一定的时间限制,机器人用它来计算当前回合的剩余时间;这让它决定如何使用剩余的转弯时间。现在,我想做的是,跟踪调试所花费的时间(该回合在断点上花费的总时间),因此我可以将其添加到剩余时间中,使其看起来像从未暂停过。
最初,我尝试使用这样的东西:

private DateTime turnTimeStarted;
public TimeSpan TurnTimeRemaining
{
    get { return (turnTimeStarted + TurnTime + TimeSpentInDebugger) - 
                      DateTime.Now; }
}

private DateTime debugStartTime;
private bool inDebugger = false;

private TimeSpan timeSpentInDebugger = new TimeSpan();
public TimeSpan TimeSpentInDebugger
{
    get
    {
         if (!inDebugger) 
             return timeSpentInDebugger;
         return timeSpentInDebugger + (DateTime.Now - debugStartTime);
    }
}

public void Break()
{
    if (Debugger.IsAttached)
    {
        debugStartTime = DateTime.Now;
        inDebugger = true;

        Debugger.Break();

        inDebugger = false;
        timeSpentInDebugger += DateTime.Now - debugStartTime;
    }
}

这样做的问题是,它在实际的Debugger.Break()语句而不是Break()方法调用上中断,所以我最终在我想要调试的代码的上下文之外。
我正在寻找的是一组类似于在调用Debugger.Break之前和之后触发的事件,以检测进入和离开断点的时间。

zphenhs4

zphenhs41#

使用Stopwatch(http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx)类,在中断前开始,中断后停止,并根据需要添加时间。

kpbwa7wx

kpbwa7wx3#

我知道这个主题已经很老了,但我仍然没有找到更好的解决方案。
关于在错误的上下文中中断,您可以通过暴露Action属性而不是方法来轻松解决这个问题:

public static class MyDebugger {
    public static Action Break => Debugger.Break;
}

然后调试器将停止在MyDebugger.Break()调用而不是Debugger.Break
您可以在返回操作之前存储时间,但主要问题是您无法判断执行何时实际恢复,因为Break()只请求停止,而不是实际执行调试过程。
为了解决这个问题,我写了一个监控方法,它测量它的执行时间,并在访问属性时在一个sperate线程上启动它。当执行时间很慢时,它将其视为时间消耗评估断点,否则,当正常执行速度检测到一定时间后,线程退出。
I share it here
你可以这样计算你的时间:

public TimeSpan TurnTimeRemaining
    => turnTimeStarted + TurnTime - Debuger.Now;

这样做的问题是,你必须利用整个线程来获得合理准确的测量结果。当你实际单步执行代码时,这并不是一个大问题,但在恢复应用程序后,你将使线程阻塞几秒钟。
更重要的是,如果监视器没有持续打开,则无法检测调试器何时命中IDE中设置的断点。
为了解决这个问题,我写了一个额外的懒惰监视器,它以较慢的时间间隔运行在一个任务上,但它不是那么准确,而且有它自己的问题。
可惜Debugger接口太差了。

相关问题