C# Console.ReadLine无法处理任务';继续

C# Console.ReadLine无法处理任务';继续,c#,task,console-application,C#,Task,Console Application,假设我有一段代码: var tasks = new Task<string>[] { ToStringAsync(1) }; Task.WhenAll(tasks).ContinueWith(r => Console.WriteLine(r.Result.First())); Console.ReadLine(); 这很好,它可以打印: > 1 > _ (Wait for user interaction) 但是,如果我将我的Console.ReadLine()

假设我有一段代码:

var tasks = new Task<string>[] { ToStringAsync(1) };
Task.WhenAll(tasks).ContinueWith(r => Console.WriteLine(r.Result.First()));
Console.ReadLine();
这很好,它可以打印:

> 1
> _ (Wait for user interaction)
但是,如果我将我的
Console.ReadLine()
移动到我的匿名操作:

var tasks = new Task<string>[] { ToStringAsync(1) };
Task.WhenAll(tasks).ContinueWith(r =>
{
    Console.WriteLine(r.Result.First());
    Console.ReadLine();
});
相反,它不等待任何输入,控制台应用程序会立即关闭


为什么
Console.ReadLine()
不工作,如果我在
ContinueWith
中执行它?

在第一个示例中,它不是
任务。当所有(任务)
时,而是
Console.ReadLine()
等待回调
任务完成。方法
WhenAll()
不等待
。ContinueWith()
因为它是独立的任务,不存在于
任务
数组中

在第二个场景中,当所有的
等待两个任务完成,但当它们完成时,您的程序将完成执行

不要忘记,如果异步执行
Console.ReadLine()
,它将阻塞执行它的
线程,而这次它不是主线程。如果在第二个场景中,您将添加
Thread.Sleep(5000)
Main
方法的末尾,它将等待5秒钟,允许用户输入文本,但不管用户是否按下“回车”键,它都会完成

未等待ReadLine时的简短示例:

    static void Main(string[] args)
    {
        Task t = new Task(() => { Console.ReadLine(); Console.WriteLine("You pressed enter"); });

        t.Start();

        Thread.Sleep(5000);
    }

//仅执行5秒

继续执行
会创建一个您也需要等待的新任务,因此只需在它之后添加一个
等待

var tasks = new Task<string>[] { ToStringAsync(1) };
Task.WhenAll(tasks)
    .ContinueWith(r =>
       {
            Console.WriteLine(r.Result.First());
            Console.ReadLine();
        })
    .Wait();
var tasks=newtask[]{ToStringAsync(1)};
Task.WhenAll(任务)
.ContinueWith(r=>
{
Console.WriteLine(r.Result.First());
Console.ReadLine();
})
.Wait();
现在,主线程将在结束程序之前等待继续完成


读线
在延续之外时,它“起作用”的原因是因为它阻塞了主线程,但您可能会以足够快的速度按enter键,使其在
写线
出现之前仍能结束程序,这取决于
任务
所花的时间。

在我看来,主线程不再等待更多指令,因此它退出应用程序,因为所有操作都是在另一个线程上完成的。您需要捕获
ContinueWith
返回的
任务
,然后等待,这样主线程就不会先结束。
    static void Main(string[] args)
    {
        Task t = new Task(() => { Console.ReadLine(); Console.WriteLine("You pressed enter"); });

        t.Start();

        Thread.Sleep(5000);
    }
var tasks = new Task<string>[] { ToStringAsync(1) };
Task.WhenAll(tasks)
    .ContinueWith(r =>
       {
            Console.WriteLine(r.Result.First());
            Console.ReadLine();
        })
    .Wait();