等待Console.ReadLine()

时间:2014-03-26 14:40:08

标签: c# asynchronous console async-await

我目前正在构建一个异步控制台应用程序,我在其中创建了类来处理应用程序的不同区域。

我创建了一个InputHandler类,我设想它将等待Console.ReadLine()输入。但是,你不能等待这样的功能(因为它不是异步),我目前的解决方案就是:

private async Task<string> GetInputAsync() {
    return Task.Run(() => Console.ReadLine())
}

运行完全正常。但是,我的(有限的)理解是调用Task.Run将触发一个新的(并行?)线程。这违背了异步方法的目的,因为新线程现在被阻塞,直到Readline()返回正确?

我知道线程是一种昂贵的资源,所以我觉得非常浪费和hacky这样做。我也试过Console.In.ReadLineAsync(),但它显然是马车? (好像挂了)。

1 个答案:

答案 0 :(得分:9)

  

我知道线程是一种昂贵的资源,所以我觉得非常浪费和hacky这样做。我也试过Console.In.ReadLineAsync(),但它显然是马车? (好像挂了)。

不幸的是,控制台流确实有令人惊讶的行为。根本原因是他们阻止以确保控制台流的线程安全。我个人认为在异步方法中阻塞是一个糟糕的设计选择,但微软决定这样做(仅适用于控制台流)和have stuck by their decision

因此,如果您确实想要异步读取,那么此API设计强制您使用后台线程(例如,Task.Run)。这不是您通常应该使用的模式,但在这种情况下(控制台流),解决它们的API是一个可接受的黑客。

  

然而,我的(有限的)理解是调用Task.Run将触发一个新的(并行?)线程。

不完全。 Task.Run会将一些工作排​​入队列,这将使其中一个线程执行代码。线程池根据需要管理线程的创建,您通常不必担心它。因此,Task.Run并不像每次实际创建新线程那样浪费。