我遇到了一些问题,我无法理解为什么会这样。 这是一个简单的例子:
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立即启动。
任何人都可以解释这种行为吗?
答案 0 :(得分:4)
这是竞争条件的理想情况。在这里,您将创建一个线程,然后启动它。但请记住,一旦您调用start
方法,线程就会延迟实际运行。可能这种延迟使您的Console.ReadKey
方法有机会进入执行流程并等待用户输入。在此阶段,Console.ReadKey
方法通过锁定Console.InternalSyncObject
来阻止您的控制台,并阻止等待输入。这种情况下阻塞的其他执行路径直到我们键入。一旦按下Key,它间接释放Console.InternalSyncObject
上的锁并允许线程继续执行。我认为,这就是你的情况。
虽然不是要替换你想要实现的内容,但是当你将Console.RedKey
替换为Console.ReadLine()
时,可以看到该线程正在执行。
答案 1 :(得分:0)
静态类Console
是线程安全的,里面有一个锁。有时ReadKey
来电会在您ThreadProc
内的来电之前锁定。它被称为“竞争条件”