【问题标题】:Why is the thread execution order in Debugging and Release modes different?为什么 Debugging 和 Release 模式下的线程执行顺序不同?
【发布时间】:2013-02-08 10:48:39
【问题描述】:

我在 Visual Studio 2010、Windows XP SP3 中运行以下 C# 代码。

在“不调试启动”中(按 Ctrl+F5 或从菜单),输出:

  • 来自main的你好
    工人问好

“开始调试”(按 F5 或从菜单)显示相反的顺序:

  • 工人问好
    来自主要的你好

检查了很多次。它是可重现和可重复的。
为什么?

using System;
using System.Threading;

namespace _5NamingThreads
{
  class ThreadNaming
  {
    static void Main()
    {
      Thread.CurrentThread.Name = "main";
      Thread worker = new Thread(Go);
      worker.Name = "worker";
      worker.Start();
      Go();
      Console.ReadLine();
    }

    static void Go()
    {
      Console.WriteLine("Hello from " + Thread.CurrentThread.Name);
    }
  }
}

更新
第二天,重新启动计算机后,我总是观察在所有模式下都可以重现的顺序,Release 和 Debug:

  • 来自main的你好
    工人问好

后续问题:
While debugging, is it possible to ensure the output without stepping into each line of code?

【问题讨论】:

    标签: c# multithreading visual-studio debugging release


    【解决方案1】:

    在调试模式下,线程启动过程需要在新线程中初始化调试上下文。这必须在函数返回之前完成,因为原始线程可能在新线程上运行。最终结果是这会减慢原始线程的速度,足以让新线程先运行。

    当然,这不是你应该永远依赖的东西。它可能会在下一版本的操作系统、库、调试器、CPU 中发生变化...

    【讨论】:

    • “在函数返回之前”是什么意思。恕我直言,你不能依赖线程调度,仅此而已。
    • 一旦创建线程的函数在原始线程中返回,该线程就可以执行与创建的线程交互的操作。因此调试器必须停止原始线程,直到它为新线程设置调试器上下文。 (当然,你不能依赖线程调度,除非你用保证控制它的机制特别强制它。见我的最后一段。)
    • 很好,感谢您对此的解释。调试器的实际工作方式对我来说一直像是黑魔法。
    【解决方案2】:

    这是因为启动新的异步线程是不确定的。换句话说,开发人员不能依赖线程以相同的顺序执行。见race conditions.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2019-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多