有时线程无法启动

时间:2013-05-07 07:28:01

标签: c# .net multithreading

我遇到了一些问题,我无法理解为什么会这样。 这是一个简单的例子:

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立即启动。

任何人都可以解释这种行为吗?

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:0)

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