c# - 有时线程没有启动

标签 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);
    }
  }
}

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

谁能解释这种行为?

最佳答案

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

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

关于c# - 有时线程没有启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16413511/

相关文章:

c# - `async void`(没有等待)与 `void` 之间有什么区别

java - 如何使用 JavaFX 使 Label 的内容在一秒后发生变化?

c++ - 最令人费解的C++堆分配错误

c# - 从 C# 调用非托管 C++ VS 6.0 MFC dll

c# - 在 linq to entities where 子句中建立两个列表之间的链接

c# - 循环引用——架构问题

c# - 如何将变量插入带有多个引号和转义字符的长字符串中?

c# - System.Drawing.Point 是一种值类型。为什么?

linux - 在GDB中调试多线程程序时如何一次继续一个线程?

c# - 对象跟随鼠标光标