Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Task.Run()写入控制台失败_C#_.net 4.5 - Fatal编程技术网

C# 使用Task.Run()写入控制台失败

C# 使用Task.Run()写入控制台失败,c#,.net-4.5,C#,.net 4.5,我的一位同事发现我们的代码有一个问题,花了一段时间才找到到底发生了什么,但下面这个简单的例子可以最好地说明这一点: // Fails class Program { static void Main(string[] args) { Task.Run(() => Console.WriteLine("Hello World")); Console.ReadKey(); } } // Works fine class Program

我的一位同事发现我们的代码有一个问题,花了一段时间才找到到底发生了什么,但下面这个简单的例子可以最好地说明这一点:

// 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();
    }
}

很明显,从主线程到控制台的任何地方写入都会允许后台线程也写入控制台,但是我们很难理解为什么会发生这种情况。有人能解释一下,从主线程写入控制台时,第一个代码段没有实现什么吗?

事实上,第一个案例没有失败。“Hello World”出现在应用程序结束之前。这是一本经典的书。在第一种情况下,来自主线程的
Console.ReadKey()
击败了任务,在第二种情况下,任务获胜。不幸的是,我不能确切地告诉您为什么写空字符串会使任务成功。

我怀疑发生了什么。我观察到:

  • 如果在启动
    ReadKey
    之前对控制台的输出执行任何操作,都可以。这包括获取
    控制台.Out
    ,但不使用它
  • 如果在
    Console.WriteLine
    调用开始之前延迟
    Console.ReadKey
    调用,则没有问题(在
    ReadKey
    等待时,您可以有多个
    WriteLine
    调用)
我怀疑第一个使用控制台的操作会获得一个初始化锁(以避免它被初始化两次),并且
ReadKey
方法会一直保持锁,直到一个键被读取为止。这当然可以解释到目前为止我运行的每个程序

虽然执行假设初始化的操作很有趣-读取
Console.Out
“修复”了问题,但从
Console.In
读取则没有

我怀疑
ReadKey
初始化了输出,因为该值仍会回显到控制台…但我不想发誓


有趣的是,使用
Console.ReadLine()
而不是
Console.ReadKey()
一开始并不会导致问题。

您没有描述失败案例中会发生什么。在我的框中,它似乎会一直挂起,直到您点击回车键,然后打印出来。@jonsket是的,这就是我看到的行为。这确实是解决方案。我认为这不对。它不像调用Console.WriteLine之后发生的那样对Console.ReadLine的调用已完成-否则,如果您等待一段时间,您将看到输出。我认为这似乎是某种初始化问题。或者更清楚地说-我相信这是一种竞争条件,但仅限于哪个调用首先启动,并且仅当
Console.ReadKey
是对控制台的第一次调用,两者都不是答案很清楚。
Console.ReadLine()
不会引起同样的问题,这当然很有趣。感谢您抽出时间