【问题标题】:Sometimes thread does not start [duplicate]有时线程不启动[重复]
【发布时间】:2013-05-01 01:55:14
【问题描述】:

我遇到了一些我不明白为什么会发生的问题。 这是一个简单的例子:

class ConsoleApp
{
  static void Main(string[] args)
  {
    Thread workThread = new Thread(ThreadProc);
    //Console.WriteLine("Starting"); // uncomment this
    workThread.Start();
    Console.ReadKey(true); // first ReadKey
    Console.ReadKey(true); // second ReadKey
  }

  static void ThreadProc()
  {
    Console.WriteLine("ThreadProc started");
    Random rnd = new Random();
    for (int i = 0; i < 5; i++)
    {
      int timeout = rnd.Next(500, 1000);
      Thread.Sleep(timeout);
      Console.WriteLine("ThreadProc {0} slept {1} ms", i, timeout);
    }
  }
}

当我运行它时,直到我按下某个键(在第一个 ReadKey 之后),workThread 才会启动。如果我取消注释第一个 Console.WriteLine,workThread 会立即启动。

谁能解释这种行为?

【问题讨论】:

  • 我复制了你的代码并尝试了这个,但是线程立即启动,不管评论或取消评论该行。
  • 我不能重复这个。这是在什么环境下运行的?
  • Alexander,尝试将 Console.ReadKey 替换为 System.Windows.Forms.Application.Run(new Form());
  • 谢谢,stackoverflow.com/questions/15143931/… 中的答案解释了一切。我尝试使用 Debug.WriteLine() 并看到该线程实际上已启动,但 Console.WriteLine 锁定了执行。

标签: c# .net multithreading


【解决方案1】:

这是竞态条件的理想情况。在这里,您正在创建一个线程并随后启动它。但请记住,一旦您在其上调用start 方法,线程实际运行就会有延迟。可能,此延迟使您的 Console.ReadKey 方法有机会进入执行流程并等待用户输入。在这个阶段,Console.ReadKey 方法通过锁定Console.InternalSyncObject 来阻塞你的控制台,并阻塞等待输入。这种情况下其他执行路径会被阻塞,直到我们键入。一旦按下 Key,这会间接释放 Console.InternalSyncObject 上的锁定并允许线程继续执行。我想,这就是你的情况。

虽然不是替换你想要实现的东西,但是当你将Console.RedKey替换为Console.ReadLine()时,你可以看到线程正在执行。

【讨论】:

  • 线程立即启动。是Console.WriteLine,等待控制台锁在它完成执行之前被释放..
【解决方案2】:

静态类Console 是线程安全的,里面有一个锁。有时ReadKey 调用会在调用ThreadProc 之前锁定。它被称为“竞争条件”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多