使用 Task.Run() 写入控制台失败 [英] Writing to the console using Task.Run() fails
问题描述
我的一位同事发现我们的代码存在问题,我们花了一段时间才弄清楚到底发生了什么,但这个简单的例子可以很好地证明这一点:
//失败课程计划{静态无效主(字符串 [] 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
调用 starts 在Console.ReadKey
调用之前,那很好(并且您可以有多个WriteLine
调用 whileReadKey
正在等待
我怀疑使用控制台的第一个操作获取了一个用于初始化的锁(以避免它被初始化两次)并且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 fetchingConsole.Out
but not using it - If you put a delay in so that the
Console.WriteLine
call starts before theConsole.ReadKey
call, it's fine (and you can have multipleWriteLine
calls whileReadKey
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屋!