4

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

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

谁能解释这种行为?

4

2 回答 2

4

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

虽然它不是要替换您要实现的目标,但您可以在替换Console.RedKey为时看到线程正在执行Console.ReadLine()

于 2013-05-07T07:47:05.233 回答
0

静态类Console是线程安全的,里面有一个锁。有时ReadKeycall 在你的ThreadProc. 它被称为“竞争条件”

于 2013-05-07T07:33:04.550 回答