1

一段时间以来,我一直在研究这个问题,对我来说很明显普通断点的放置会极大地影响程序的运行时行为。

我在这里说的是条件断点,例如,当设置断点条件时,var == null这种情况永远不会发生,但是当我删除断点时,这种var == null情况经常发生。

可以吗?

附录:

好吧,我的代码是多线程的,因此很难发布代码以重现错误。基本上我有两个线程。一种是将项目放入队列中,另一种是将项目永久地从队列中取出。在下面的代码片段中,我遇到的情况是第一个线程从不将空项排入队列,但由于某种原因,它们正在寻找进入队列的方式。这让我插入 if 语句以防止出现NullReferenceException。虽然是一个临时的解决方法,但我的程序确实从那时起运行了。然后我对空项从队列中出列的频率很感兴趣,我在带有条件的 if 语句的行中放置了一个条件断点inv == null. 现在的效果是,当有断点时 inv 似乎永远不会为空,而当没有断点时 inv 似乎通常为空。

public void _dequeue () {

            while (!Signals.TerminateSignal.WaitOne(0, false)) {

                if (Signals.DequeueSignal.WaitOne()) {

                    lock (Queue) {

                        IInvocation inv;
                        Queue.TryDequeue(out inv);

                        // Conditional Breakpoint
                        if (inv != null)
                            inv.Invoke();

                        _poolHooks[PoolIndex].DecrementWaiting();
                        _poolHooks[PoolIndex].IncrementPending();

                        if (Queue.Count == 0) Signals.DequeueSignal.Reset();

                    }
                }
            }
        }

当队列中的某些项目开始为空项目时,我的问题再次开始,尽管我从未添加空项目。即使出于这个原因,我也放置了一条在有空值时抛出异常的行。异常永远不会被抛出,但我的队列中仍然有空项目,我不知道为什么。

public static void EnqueueInvocation (int poolIndex, IInvocation inv ) {

        if (inv == null) throw new Exception("Red Alert");

        lock (_deqThreads[poolIndex].Queue) {

            _poolHooks[poolIndex].IncrementWaiting();


            _deqThreads[poolIndex].Queue.Enqueue(inv);
            _deqThreads[poolIndex].Signals.DequeueSignal.Set();
        }
    }
4

3 回答 3

10

“条件断点”肯定会影响时间。如果您有竞争条件,它肯定会改变行为。您也可以开始看到超时。

这是因为在大多数处理器上不存在真正的“条件断点”。您实际上拥有的是“断点,有条件地随后自动恢复执行”,即使条件不满足,这也很慢,因为调试器断点处理程序必须运行,读取内存,测试条件,然后发出继续。


现在您已经发布了代码,我想我看到了问题所在。

您没有检查TryDequeue. 当没有什么要出队时, inv 将是null,不是因为null被放入队列,而是因为队列中根本没有项目。

于 2012-07-10T17:25:36.727 回答
1

这些断点根本不应该影响您的代码执行(除了减慢标记的代码行)。你确定你不是不小心写var = null的或类似的东西吗?这也可能是一些与时间相关的问题(例如,您的代码较慢,因此一些多线程情况/竞争条件很少发生),但最终真的很难说 - 至少它不是因为使用这些而导致的一般问题或劣势.

于 2012-07-10T17:28:43.650 回答
1

无论我在哪里设置断点,我都看不到 x 的评估行为有什么不同。

    static void Main(string[] args)
    {
        var x = new object();
        if (x == null)
        { Console.WriteLine("x is null"); }
        else
        { Console.WriteLine(x.ToString()); }
        x = null;
        if (x == null)
        { Console.WriteLine("x is null"); }
        else
        { Console.WriteLine(x.ToString()); }
    }

System.Object
x 为空

于 2012-07-10T17:37:23.053 回答