12

次のコードを使用して新しいコンソールアプリを起動します-

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

これは私が期待するように動作し、Task.Delayがブロックしないため、次の行に直接進み、「hi」を出力します。

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

これは現在、ドキュメントで見つけることができます:

標準入力ストリームの読み取り操作は同期して実行されます。つまり、指定された読み取り操作が完了するまでブロックします。これは、 ReadLineAsyncなどの非同期メソッドがInプロパティによって返されるTextReaderオブジェクトで呼び出された場合でも当てはまります。

于 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 に答える