为什么Console.In.ReadLineAsync阻止?

时间:2013-02-06 08:28:44

标签: c# async-await

使用以下代码启动新的控制台应用程序 -

class Program
{
    static void Main(string[] args)
    {
        while (true)
        {
            Task<string> readLineTask = Console.In.ReadLineAsync();

            Debug.WriteLine("hi");
        }
    }
}

Console.In.ReadLineAsync正在阻止,并且在控制台中输入一行之前不会返回..所以&#34;嗨&#34;永远不会被写入控制台。

在Console.In.ReadLineAsync上使用await也会阻止。

据我了解,新的Async CTP方法不会阻止。

这是什么原因?


这是另一个例子

static void Main(string[] args)
{
    Task delayTask = Task.Delay(50000);

    Debug.WriteLine("hi");
}

这表现如我所料,它直接进入下一行并打印&#34; hi&#34;因为Task.Delay没有阻止。

3 个答案:

答案 0 :(得分:5)

达里尔在这里提供了答案 http://smellegantcode.wordpress.com/2012/08/28/a-boring-discovery/

似乎ReadLineAsync实际上并没有做它应该做的事情。框架中的错误。

我的解决方案是在循环中使用ThreadPool.QueueUserWorkItem,因此每次调用ReadLineAsync都是在新线程上完成的。

答案 1 :(得分:3)

现在可以在the documentation

中找到
  

标准输入流上的读操作同步执行。也就是说,它们会阻塞,直到指定的读取操作完成。即使在ReadLineAsync属性返回的TextReader对象上调用了异步方法(例如In),也是如此。

答案 2 :(得分:1)

另一种解决方案:

static void Main()
{
    using (var s = Console.OpenStandardInput())
    using (var sr = new StreamReader(s))
    {
        Task readLineTask = sr.ReadLineAsync();
        Debug.WriteLine("hi");
        Console.WriteLine("hello");

        readLineTask.Wait();// When not in Main method, you can use await. 
                            // Waiting must happen in the curly brackets of the using directive.
    }
    Console.WriteLine("Bye Bye");
}