我的一位同事在我们的代码中发现了一个问题,并且花了一段时间来确切地查找正在发生的事情,但最好通过这个简单的例子来证明:
// Fails
class Program
{
static void Main(string[] args)
{
Task.Run(() => Console.WriteLine("Hello World"));
Console.ReadKey();
}
}
// Works fine
class Program
{
static void Main(string[] args)
{
Console.Write(String.Empty);
Task.Run(() => Console.WriteLine("Hello World"));
Console.ReadKey();
}
}
从中解决这个问题很清楚,从主线程到任何地方写入控制台都会允许后台线程写入控制台,但是我们很难理解为什么会发生这种情况。任何人都可以解释从主线程写入控制台的内容是什么,第一个片段没有?
答案 0 :(得分:5)
实际上,第一种情况并没有失败。应用程序结束前出现“Hello World”。这是一个经典的Race Condition。在第一种情况下,来自主线程的Console.ReadKey()
击败任务,而在第二种情况下,任务获胜。不幸的是,我无法告诉你为什么写空字符串会让任务获胜。
答案 1 :(得分:5)
我怀疑发生了什么事。我观察到的是:
ReadKey
之前使用控制台的输出执行任何,那就没关系。这包括提取Console.Out
但不使用Console.WriteLine
来电之前设置了Console.ReadKey
来电> ,那么就可以了(并且您可以进行多次WriteLine
次来电< em> while ReadKey
正在等待我怀疑使用控制台的第一个操作获取初始化锁定(以避免它被初始化两次)并且ReadKey
方法保持锁定直到一个键已被阅读。这肯定会解释我到目前为止所运行的所有程序。
执行假设初始化的操作很有趣 - 阅读Console.Out
“修复了”问题,但是从Console.In
读取却没有。
我怀疑ReadKey
初始化输出,因为该值仍然会回显到控制台......但我不想发誓。
有趣的是,使用Console.ReadLine()
代替Console.ReadKey()
并不会导致问题。