在调试模式下,当我单步进入和单步跳过一个函数时,程序运行方式不同。

4

我有一个名为GetAlertData()的函数,它返回一个数据表。我这样调用它:

var dt = GetAlertData()

调试模式下的行为:

情况1: 当我一直按F11并进入GetAlertData函数时,一切正常,我得到了正确的表格。

情况2: 当我在该函数上按F10并跨过它时,GetAlertData返回一个所有值都填充为零(不正确)的表格。(我的表格的列都是浮点数据类型)

在发布模式下,行为与在调试模式下按F10相同,即我再次得到所有零。

有什么想法或者我可以尝试找出原因吗?谢谢..

编辑:我的GetAlertData函数大致如下..

internal static DataSet GetAlertData()
        {
            using (var sqlConnection = new SqlConnection(Constants.ConnectionString))
            {
                const string sproc = @"[spo_GetAlertData]";
                var cmd = new SqlCommand(sproc, sqlConnection) {CommandType = CommandType.StoredProcedure};

                cmd.Parameters.Add("@TimeWindow", SqlDbType.Int);
                cmd.Parameters["@TimeWindow"].Value =2
                cmd.Parameters.Add("@ThresholdTime", SqlDbType.Int);
                cmd.Parameters["@ThresholdTime"].Value = 2
                var dsAnalysis = new DataSet();
                var da = new SqlDataAdapter(cmd);
                da.Fill(dsAnalysis);
                if (dsAnalysis.Tables.Count > 0 && dsAnalysis.Tables[0].Rows.Count > 0)
                    return dsAnalysis;
                return null;
            }
        }

你是如何查看这个问题的?在可视化工具中吗?还是在调试器本地变量中? - leppie
你为什么决定将这个方法设为静态的?通常这种代码是基于实例实现的(非静态)。将其改为实例方法可能会解决潜在的线程问题。同时,考虑使用锁(lock(_synchObj))进行同步以保护它。 - Paul Sasik
你是否在情况1中看到数据,仅在GetAlertData内部,还是在返回给调用者后也能看到? - Richard Anthony Freeman-Hein
我可以在情况1中看到数据。 - Hari Menon
3个回答

2
考虑使用F11和F10(分别是步入和跳过方法)的执行时间差异。 F11进入函数,因此使您在该逻辑线程中停留的时间比F10更长,后者跳过代码,允许其以全速执行。
关键是,当应用程序有更多处理时间时,由于您使用F11花费更多时间来步进和进入代码,因此您很可能会有定时/线程问题得到缓解。这就是为什么发布更多的行为与F10行为相匹配,即更快的执行速度。
我猜在问题区域周围添加Thread.Sleep(250)之类的内容也会有所帮助,但我不建议这样做。这是最后一招最好用于测试时间假设的操作。您需要弄清楚正在同时运行什么可能导致这种情况。

啊... 终于搞定了。一个简单的 thread.sleep 不行... 一直在苦苦寻找原因——是两个线程从同一个数据库进行修改所导致的问题.. 你的答案最接近 :) - Hari Menon

1

没有看到 GetAlertData 的源代码,我只能猜测您已设置了一些监视变量,这些变量访问具有副作用的属性或其他会改变结果的内容。这些监视变量仅在您进入 GetAlertData 方法时才会生效。


1
这里最可能的问题是您有一个具有副作用的属性或.ToString,在您进行步进时在自动/本地/监视窗口中被评估。在F11情况下,此属性被放置在其中一个窗口中,进行评估并且其副作用导致方案工作。在F10情况下,它不会发生,因此方案失败。
您可以通过禁用隐式函数评估来轻松测试此功能。
  • 工具 -> 选项
  • 调试器
  • 取消选中“启用隐式属性和调用”复选框
  • 重新运行您的方案

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接