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();