Writing to the console using Task.Run() fails

北战南征 提交于 2019-12-09 14:48:00

问题


A colleague of mine found an issue with our code and it took a while to hunt down exactly what was happening, but it can be best demonstrated by this simple example:

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

It’s clear from playing around with this that writing to the console anywhere from the main thread will allow the background thread to write to the console also, but we are struggling to understand why this is happening. Can anyone explain what writing to the console from the main thread achieves that the first snippet does not?


回答1:


I have a suspicion as to what's going on. What I've observed:

  • If you do anything with the console's output before starting the ReadKey, it's fine. This includes fetching Console.Out but not using it
  • If you put a delay in so that the Console.WriteLine call starts before the Console.ReadKey call, it's fine (and you can have multiple WriteLine calls while ReadKey is waiting

I suspect that the first operation to use the console acquires a lock for initialization (to avoid it being initialized twice) and that the ReadKey method keeps hold of the lock until a key has been read. That would certainly explain every program I've run so far.

The operations which perform the hypothesized initialization are interesting though - reading Console.Out "fixes" the issue, but reading from Console.In doesn't.

I suspect that ReadKey initializes the output because the value is still echoed to the console... but I wouldn't like to swear to it.

Interestingly, using Console.ReadLine() instead of Console.ReadKey() doesn't cause the problem in the first place.




回答2:


Actually, the first case doesn't fail. "Hello World" appears just before the Application ends. This is a classical Race Condition. In the first case,Console.ReadKey() from the main thread beats the task, and in the second case, the task wins. Unfortunately, I cannot tell you Exactly why writing the empty string makes the task win.



来源:https://stackoverflow.com/questions/14384064/writing-to-the-console-using-task-run-fails

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!