在C#中的控制台应用程序asynchronous?

我有这个简单的代码:

public static async Task<int> SumTwoOperationsAsync() { var firstTask = GetOperationOneAsync(); var secondTask = GetOperationTwoAsync(); return await firstTask + await secondTask; } private async Task<int> GetOperationOneAsync() { await Task.Delay(500); // Just to simulate an operation taking time return 10; } private async Task<int> GetOperationTwoAsync() { await Task.Delay(100); // Just to simulate an operation taking time return 5; } 

大。 这个编译。

但是让我们说我有一个控制台应用程序,我想运行上面的代码(调用SumTwoOperationsAsync()

  static void Main(string[] args) { SumTwoOperationsAsync(); } 

但是我读过(当使用sync )时,我必须一路上同步:

问题 :这是否意味着我的Mainfunction应该被标记为async

那么它不能是因为有一个编译错误:

入口点不能用“asynchronous”修饰符标记

如果我了解asynchronous的东西,线程将进入Main函数—-> SumTwoOperationsAsync —->将调用这两个函数,并将出。 但直到SumTwoOperationsAsync

我错过了什么?

在大多数项目types中, async “向上”和“向下”将在async void事件处理程序结束或返回一个Task到您的框架。

但是,控制台应用程序不支持这一点。

你可以在返回的任务上做一个Wait

 static void Main() { MainAsync().Wait(); // or, if you want to avoid exceptions being wrapped into AggregateException: // MainAsync().GetAwaiter().GetResult(); } static async Task MainAsync() { ... } 

或者你可以使用你自己的上下文,就像我写的那样 :

 static void Main() { AsyncContext.Run(() => MainAsync()); } static async Task MainAsync() { ... } 

有关async控制台应用程序的更多信息在我的博客上 。

这是最简单的方法

 static void Main(string[] args) { Task t = MainAsync(args); t.Wait(); } static async Task MainAsync(string[] args) { await ... } 

作为一个快速和非常有限的解决scheme:

Task.Result

Task.Result和Task.Wait都不允许在与I / O一起使用时提高可伸缩性,因为它们将导致调用线程保持阻塞,等待I / O结束。

当你在一个不完整的Task上调用.Result时,执行该方法的线程必须等待任务完成,同时阻止线程执行其他有用的工作。 这就消除了任务asynchronous性的好处。

notasync

我的解决scheme JSONServer是我为在控制台窗口中运行HttpListener服务器而编写的类。

 class Program { public static JSONServer srv = null; static void Main(string[] args) { Console.WriteLine("NLPS Core Server"); srv = new JSONServer(100); srv.Start(); InputLoopProcessor(); while(srv.IsRunning) { Thread.Sleep(250); } } private static async Task InputLoopProcessor() { string line = ""; Console.WriteLine("Core NLPS Server: Started on port 8080. " + DateTime.Now); while(line != "quit") { Console.Write(": "); line = Console.ReadLine().ToLower(); Console.WriteLine(line); if(line == "?" || line == "help") { Console.WriteLine("Core NLPS Server Help"); Console.WriteLine(" ? or help: Show this help."); Console.WriteLine(" quit: Stop the server."); } } srv.Stop(); Console.WriteLine("Core Processor done at " + DateTime.Now); } }