【发布时间】:2013-02-15 03:20:56
【问题描述】:
在多线程程序中使用Console.ReadKey() 时遇到一个奇怪的问题。
我的问题是:为什么会这样?这是一个错误,还是因为我滥用Console?
(请注意,控制台应该是线程安全的,according to the documentation。)
用代码最容易解释:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("X"); // Also try with this line commented out.
Task.Factory.StartNew(test);
Console.ReadKey();
}
private static void test()
{
Console.WriteLine("Entering the test() function.");
Thread.Sleep(1000);
Console.WriteLine("Exiting the test() function.");
}
}
}
如果你运行它并且不按任何键,你认为会打印出什么?
答案正是你所期望的:
X
Entering the test() function.
Exiting the test() function.
现在注释掉Console.WriteLine("X") 并再次运行它(不按任何键)。
我希望看到这个输出:
Entering the test() function.
Exiting the test() function.
相反,我看到什么都没有。然后当我按下一个键时,它会说:
Entering the test() function.
...就是这样。程序退出(当然)并且没有时间进入下一个WriteLine()。
我觉得这种行为很神秘。这很容易解决,但我很好奇为什么会这样。
[编辑]
如果我在Console.ReadKey() 之前添加一个Thread.Sleep(1),它会按预期工作。当然,这不是必需的,因为 Console.ReadKey() 无论如何都应该永远等待。
所以看起来它可能是某种竞争条件?
更多信息:Servy 发现(并且我已经复制)Console.WriteLine("Entering the test() function.") 行被阻塞,直到按下任何键。
构建配置
Visual Studio 2012,Windows 7 x64,四核,英语(英国)。
我尝试了 .Net4、.Net4.5、x86、AnyCPU 以及调试和发布的所有组合,但它们都不能在我的 PC 上运行。但是发生了一件非常奇怪的事情。当我第一次尝试 .Net4 的 AnyCPU 版本时它开始工作,但随后又停止工作。看起来很像只影响某些系统的竞争条件。
【问题讨论】:
-
根据我的实验,第一次写入控制台时会进行一些初始化,以设置并发读写的框架。如果在您第一次调用
ReadKey之前已经写入了控制台,那么您会没事的,但它从未被写入过这种特殊的行为。正如你所说,很容易解决,但很好奇。 -
当你明确强制 Console.Out 刷新时会发生什么?
-
@Krypes
Console.WriteLine阻塞(基于我的实验),而不是继续进行而不做任何事情,因此没有机会刷新它。 -
@Servy 我逐字使用了他的代码,它没有遇到他遇到的相同问题。这是删除了 WriteLine 方法。
-
@Justin 我能够完全按照描述复制它。这可能是版本相关的错误。
标签: c# multithreading console-application