【问题标题】:Why does Console.In.ReadLineAsync block?为什么 Console.In.ReadLineAsync 会阻塞?
【发布时间】:2013-02-06 08:28:44
【问题描述】:

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

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

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

Console.In.ReadLineAsync 处于阻塞状态,直到在控制台中输入一行后才会返回。因此“Hi”永远不会被写入控制台。

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

据我了解,新的异步 CTP 方法不会阻塞。

这是什么原因?


这是另一个例子

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

    Debug.WriteLine("hi");
}

这符合我的预期,它直接进入下一行并打印“hi”,因为 Task.Delay 没有阻塞。

【问题讨论】:

    标签: c# async-await


    【解决方案1】:

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

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

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

    【讨论】:

    【解决方案2】:

    现在可以在the documentation

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

    【讨论】:

      【解决方案3】:

      另一种解决方案:

      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");
      }
      

      【讨论】:

        猜你喜欢
        • 2012-08-23
        • 1970-01-01
        • 2021-06-10
        • 2017-07-14
        • 2010-10-13
        • 1970-01-01
        • 2019-02-18
        • 2021-08-29
        相关资源
        最近更新 更多