自上一步(Visual Studio)以来,进程或线程已更改

时间:2013-11-23 17:30:10

标签: .net visual-studio debugging

我有一个C#.NET 控制台应用程序,使用SmtpClient发送电子邮件。

我在下面的代码中遇到以下行为:

  1. 在第35行以上的位置设置断点
  2. 点击断点,逐步进入第30,32行等
  3. 在它击中第35行之前,它再次跳回到第28行
  4. 在某些时候,我得到“自上一步以来流程或线程已经改变”消息
  5. 跳跃似乎是随机的
  6. The process or thread has changed since last step screen shot

    为什么我的断点会跳转?

    该消息的含义是什么?

    我的代码有什么问题吗?

    Here's another similar question on Stackoverflow。可能是同样的事情,但它是ASP.NET)


    Per Hans Passants的提示如下。

    此版本仍然允许竞争条件:在我的计时器的事件处理程序中切换Timer.AutoReset属性,以避免在代码运行时重新进入。

    private void OnTimerElapsed(object source, ElapsedEventArgs e)
    {
      timer.AutoReset = false; // prevent another Elapsed event
      MyClass.SendMail(smtpServer, account, password); // do stuff
      timer.AutoReset = true; // allow another Elapsed event
    }
    

    最终版本:在AutoReset已设置为false的情况下初始化计时器,然后在您的Elapsed事件处理程序结束时再次调用Timer.Start()

    public void Start()
    {
      timer = new Timer(checkInterval);
      timer.Elapsed += new ElapsedEventHandler(OnTimerElapsed);
      timer.AutoReset = false; // prevent race condition
      timer.Start();
    }
    
    private void OnTimerElapsed(object source, ElapsedEventArgs e)
    {
       bool exceptionIsNasty = false;
       try {
          MyClass.SendMail(smtpServer, account, password); // do stuff
       }
       catch (Exception ex) {
          // Log exception, set exceptionIsNasty to true if the mailing should be stopped
          //...
       }
       finally {
           if (!exceptionIsNasty) timer.Start();  // allow another Elapsed event
       }
    }
    

3 个答案:

答案 0 :(得分:7)

你有多个线程执行相同的方法,它们都会遇到相同的断点。当您继续步进时,调试器无法准确猜测它应该显示哪个线程的状态。所以你只是得到一个警告,你现在正在查看不同线程的状态。局部变量值可能不同。当然,执行位置也是高亮变化的原因。

显然,这会使调试变得更加困难。如果你仍然从代码中获取错误,只想启动一个线程,你想避免这种情况。除此之外,临时解决方法是使用Debug + Windows + Threads,右键单击其中一个线程并选择Freeze。别忘了再次解冻。

答案 1 :(得分:1)

如果您无法在一个线程中运行来进行调试,或者不想更改某些内容来进行调试, 为了使调试更容易,您还可以使用 filter为true ThreadId == xxxxx(右键单击断点)。

使用常规断点中断所需的方法,在“线程”窗口(“调试”->“ Windows”->“线程”)中查看哪个线程号是当前线程号(会有一个箭头)。根据我的建议,下一个断点可能是有条件的。

请注意,在另一次运行中,线程ID将更改,您必须在Breakpoints窗口中对其进行更新。

答案 2 :(得分:0)

  1. 设置您要开始调试的条件断点
  2. 从调试中选择所有线程>windows>threads 然后选择所有线程 ctr + A 然后 ctr + 单击您当前正在调试的线程,右键单击并选择冻结。