12

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

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

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

Console.In.ReadLineAsync 是阻塞的,直到在控制台中输入一行才会返回。所以“嗨”永远不会被写入控制台。

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

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

这是什么原因?


这是另一个例子

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

    Debug.WriteLine("hi");
}

这正如我预期的那样,它直接进入下一行并打印“hi”,因为 Task.Delay 不会阻塞。

4

3 回答 3

7

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

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

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

于 2013-02-12T21:12:55.747 回答
4

现在可以在文档中找到:

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

于 2017-08-30T18:55:07.920 回答
2

另一种解决方案:

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");
}
于 2018-07-18T14:07:49.147 回答