【问题标题】:Program runs differently when I step into and when I setp over a function in debug mode当我进入和在调试模式下设置函数时,程序运行方式不同
【发布时间】:2011-04-02 23:31:19
【问题描述】:

我有一个函数GetAlertData(),它返回一个数据表。我将其调用为:

var dt = GetAlertData()

调试模式下的行为:

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

案例 2:当我对该函数执行 F10 并跳过它时,GetAlertData 返回一个表,其中所有值都填充为零(不正确)。 (我表的列都是float数据类型)

在发布模式下,行为与在调试模式下按 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;
            }
        }

【问题讨论】:

  • 你怎么看这个?在可视化器中?还是调试器本地人?
  • 您为什么决定将方法设为静态?这种类型的代码通常实现为基于实例的(非静态的)。简单地使其成为实例方法可能会解决潜在的线程问题。还考虑通过 lock(_synchObj) 进行一些同步以保护它
  • 您是否看到案例 1 中的数据,仅在 GetAlertData 中,还是在返回给调用者之后?
  • 情况1可以一路看到数据

标签: c# .net visual-studio visual-studio-2008 debugging


【解决方案1】:

要考虑的一件事是使用 F11 和 F10 的执行时间差异(分别进入和跳过方法)。 F11 进入一个函数,因此使您在该逻辑线程中的时间比 F10 更长,后者跨越代码允许它全速执行。

关键是,当应用程序有更多的处理时间时,您很可能会遇到计时/线程问题,因为您需要更多时间来单步执行并使用 F11 进入代码。这就是为什么发布更多的行为匹配 F10 的行为,更快的执行。

我猜想在问题区域周围喷洒类似Thread.Sleep(250) 的东西也会有所帮助,但我不建议这样做。这是绝对不得已的行动,最好用于测试时间假设。您需要找出可能导致这种情况的并发运行的原因。

【讨论】:

  • 啊……终于明白了。一个简单的 thread.sleep 没有做到这一点......努力寻找原因 - 这是从同一个数据库修改的两个线​​程的不良交互......你的答案是最接近的:)
【解决方案2】:

没有看到 GetAlertData 的源代码,我只能猜测您设置了一些监视变量来访问属性或具有改变结果的副作用的东西。只有当您进入 GetAlertData 方法时,手表才会进入范围。

【讨论】:

    【解决方案3】:

    这里最可能的问题是您有一个属性或 .ToString 具有副作用,当您踏步时正在自动/本地/监视窗口中进行评估。在 F11 情况下,此属性被放置在其中一个窗口中,进行评估,它的副作用会导致场景工作。在 F10 场景中,它不会发生并且场景失败。

    您可以通过禁用隐式函数评估来轻松测试这一点。

    • 工具 -> 选项
    • 调试器
    • 取消选中“启用隐式属性和调用”复选框
    • 重新运行您的场景

    【讨论】:

      猜你喜欢
      • 2010-12-22
      • 2016-05-12
      • 1970-01-01
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多