C#: 在控制台应用程序的Main方法中调用异步方法会导致编译失败

6

我有一个非常简单的代码片段,用于测试如何在Main()方法中调用Task<>方法。

using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
    private static async Task<int> F1(int wait = 1)
    {
        await Task.Run(() => Thread.Sleep(wait));
        Console.WriteLine("finish {0}", wait);
        return 1;
    }

    public static async void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
        var task = F1();
        int f1 = await task;
        Console.WriteLine(f1);
    }
}

它不能编译,原因如下:

(1) F1 是异步的,因此 Main() 必须是 "async"。

(2) 编译器报错:

error CS5001: Program does not contain a static 'Main' method suitable for an entry point

所以如果我移除Main中的“async”,编译器会报错:
error CS4033: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.

我可以在这里添加或移除 "async" 关键字。该如何使其正常工作?非常感谢。


5
编译器已经告诉你了,考虑用“async”修饰符标记此方法,并将其返回类型更改为“Task”。尝试使用public static async Task Main() - Pavel Anikhouski
1
这个回答解决了你的问题吗?无法在控制台应用程序的'Main'方法上指定'async'修饰符 - yaakov
Main with async should be returning Task not void - Ehsan Sajjad
你需要一个引导方法,可能命名为MainAsync(string[] args),它返回一个Task。然后从Main调用该方法,无需使用async和await保留字。例如:MainAsync(args).GetAwaiter().GetResult(); - Ryan Naccarato
1个回答

18

您的Main方法与这里列出的一种有效签名不符合规范。

您可能希望使用以下内容:

public static async Task Main(string[] args)

需要返回一个Task,以便运行时知道方法何时完成;这不能通过void确定。

编译器通过生成一个合成入口点来实现此目的:

private static void $GeneratedMain(string[] args) => 
    Main(args).GetAwaiter().GetResult();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接