这个问题在这里已经有了答案:Can't specify the 'async' modifier on the 'Main' method of a console app (18 answers) Closed 5 years ago。
我有这个简单的代码:
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
时)我必须一直同步 up 和 down:
这是否意味着我的 Main
函数应标记为 async
?
嗯,不可能是因为有编译错误:
入口点不能用“异步”修饰符标记
如果我理解异步内容,线程将进入 Main
函数 → SumTwoOperationsAsync
→ 将调用这两个函数并退出。但直到 SumTwoOperationsAsync
我错过了什么?
在大多数项目类型中,您的 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()
{
...
}
或者您可以use your own context like the one I wrote:
static void Main()
{
AsyncContext.Run(() => MainAsync());
}
static async Task MainAsync()
{
...
}
async
控制台应用程序的更多信息是 on my blog。
这是最简单的方法
static void Main(string[] args)
{
Task t = MainAsync(args);
t.Wait();
}
static async Task MainAsync(string[] args)
{
await ...
}
作为一种快速且范围广泛的解决方案:
Task.Result 和 Task.Wait 在与 I/O 一起使用时都不允许提高可伸缩性,因为它们会导致调用线程保持阻塞等待 I/O 结束。
当您在不完整的任务上调用 .Result 时,执行该方法的线程必须坐下来等待任务完成,这会阻止线程同时执行任何其他有用的工作。这否定了任务的异步性质的好处。
我的解决方案。 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);
}
}
SumTwoOperationsAsync
...对吗? (假设 Main 调用方法未标记为异步)async
一起工作。catch
捕获。如果这不是您所看到的,我建议您使用最小的代码示例提出您自己的问题。