使用 Task.Run() 写入控制台失败 [英] Writing to the console using Task.Run() fails

查看:36
本文介绍了使用 Task.Run() 写入控制台失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的一位同事发现我们的代码存在问题,我们花了一段时间才弄清楚到底发生了什么,但这个简单的例子可以很好地证明这一点:

//失败课程计划{静态无效主(字符串 [] args){Task.Run(() => Console.WriteLine("Hello World"));Console.ReadKey();}}//工作正常课程计划{静态无效主(字符串 [] args){Console.Write(String.Empty);Task.Run(() => Console.WriteLine("Hello World"));Console.ReadKey();}}

很明显,从主线程写入控制台的任何地方都将允许后台线程也写入控制台,但我们正在努力理解为什么会发生这种情况.谁能解释一下从主线程向控制台写入的内容,而第一个代码段没有做到这一点?

解决方案

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

  • 如果您在启动 ReadKey 之前对控制台的输出做了任何,那就没问题了.这包括获取 Console.Out 但不使用它
  • 如果您延迟以便 Console.WriteLine 调用 startsConsole.ReadKey 调用之前,那很好(并且您可以有多个 WriteLine 调用 while ReadKey 正在等待

我怀疑使用控制台的第一个操作获取了一个用于初始化的锁(以避免它被初始化两次)并且ReadKey方法保持着这个锁直到读取了密钥.这当然可以解释我迄今为止运行的每个程序.

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

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

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

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?

解决方案

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.

这篇关于使用 Task.Run() 写入控制台失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆