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

Posted

技术标签:

【中文标题】入口点不能用“异步”修饰符标记【英文标题】:An entry point cannot be marked with the 'async' modifier 【发布时间】:2021-09-19 09:52:38 【问题描述】:

我从this 链接复制了以下代码。但是当我编译此代码时,我得到一个入口点不能用'async'修饰符标记。如何使这段代码可编译?

class Program

    static async void Main(string[] args)
    
        Task<string> getWebPageTask = GetWebPageAsync("http://msdn.microsoft.com");

        Debug.WriteLine("In startButton_Click before await");
        string webText = await getWebPageTask;
        Debug.WriteLine("Characters received: " + webText.Length.ToString()); 
    

    private static async Task<string> GetWebPageAsync(string url)
    
        // Start an async task. 
        Task<string> getStringTask = (new HttpClient()).GetStringAsync(url);

        // Await the task. This is what happens: 
        // 1. Execution immediately returns to the calling method, returning a 
        //    different task from the task created in the previous statement. 
        //    Execution in this method is suspended. 
        // 2. When the task created in the previous statement completes, the 
        //    result from the GetStringAsync method is produced by the Await 
        //    statement, and execution continues within this method. 
        Debug.WriteLine("In GetWebPageAsync before await");
        string webText = await getStringTask;
        Debug.WriteLine("In GetWebPageAsync after await");

        return webText;
    

    // Output: 
    //   In GetWebPageAsync before await 
    //   In startButton_Click before await 
    //   In GetWebPageAsync after await 
    //   Characters received: 44306

【问题讨论】:

你不能用异步标记Main @JCL:如何在 main 方法中调用 async/awai 方法 您可以在this link 上找到有关 async 和 await 的所有信息。我不确定你的概念是否正确。 我知道在 wpf 中它工作正常。但是对于演示,我已经创建了控制台,我想在控制台中进行测试 只需从Main函数中获取你想要异步调用的代码,然后从Main中的代码调用你的函数。 【参考方案1】:

错误信息完全正确:Main()方法不能是async,因为当Main()返回时,应用程序通常会结束。

如果你想制作一个使用async 的控制台应用程序,一个简单的解决方案是创建一个async 版本的Main() 并在真实Main() 的基础上同步Wait()

static void Main()

    MainAsync().Wait();


static async Task MainAsync()

    // your async code here

这是混合awaitWait() 是个好主意的少数情况之一,您通常不应该这样做。

更新:Async Main 是supported in C# 7.1。

【讨论】:

wait() 无效。等待后如何得到结果? @bilalfazlani 什么样的结果? Main() 通常不返回任何内容。在任何情况下,如果您有一个Task&lt;T&gt;(即带有结果的Task),您可以使用Result 而不是Wait()【参考方案2】:

从 C# 7.1 开始,Main 方法有 4 个新签名,可以使其成为 async(Source, Source 2, Source 3):

public static Task Main();
public static Task<int> Main();
public static Task Main(string[] args);
public static Task<int> Main(string[] args);

您可以使用async 关键字标记您的Main 方法,并在Main 中使用await

static async Task Main(string[] args)

    Task<string> getWebPageTask = GetWebPageAsync("http://msdn.microsoft.com");

    Debug.WriteLine("In startButton_Click before await");
    string webText = await getWebPageTask;
    Debug.WriteLine("Characters received: " + webText.Length.ToString()); 

C# 7.1 在 Visual Studio 2017 15.3 中可用。

【讨论】:

作为脚注,您需要更改项目构建设置以使用特定的次要 C# 版本,否则它将默认为 C#7.0。这将使您能够在Main 上使用async 关键字。【参考方案3】:

我正在使用 C# 8,它工作正常。

static async Task Main(string[] args)

   var response = await SomeAsyncFunc();
   Console.WriteLine("Async response", response);

或不带“await”关键字。

static void Main(string[] args)

   var response = SomeAsyncFunc().GetAwaiter().GetResult();
   Console.WriteLine("Async response", response);

【讨论】:

【参考方案4】:

链接示例中的代码与您的代码之间的区别在于您尝试使用 async 修饰符标记 Main() 方法 - 这是不允许的,并且错误说明了这一点 - @987654323 @方法是应用程序的“入口点”(它是在你的应用程序启动时执行的方法),不允许是async

【讨论】:

如何在 main 方法中调用 async/awai 方法【参考方案5】:

将您的异步代码包装在 MainAsync() 中 - 这是一个异步函数 然后拨打MainAsync().GetAwaiter().GetResult();

【讨论】:

以上是关于入口点不能用“异步”修饰符标记的主要内容,如果未能解决你的问题,请参考以下文章

tornado异步原理

“注意:配置保留入口点..,但不是描述符类”错误?

为啥我不能在 C# 应用程序中使用泛型类型作为入口点?

为啥使用“ld -e”选项不能更改 ELF 入口点 0x8048000?

java程序入口main()方法浅析

Java程序入口:main()方法讲解