首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# Main 入口點也能 await?教你三種在 Program.cs 使用異步等待的姿勢

     編輯:關於C#

C# 7.1 之前,Main 不支援 async 修飾詞,直接寫 async static void Main() { await ... } 會編譯失敗。本文示範三種繞過限制的標準寫法,讓主控台應用程式一進門就能優雅地 await。

為什麼 Main 不能直接 async?

await 需要外層方法標記 async,但編譯器生成的進入點簽名固定為 static void Main() 或 static int Main(),無法加 async。強行加上會得到 CS4009 錯誤:「入口點不能標記為 async」。

解法一:分離非同步方法(最推薦,C# 7.1+ 可直接用 async Main)

static void Main(string[] args) {
    RunAsync().GetAwaiter().GetResult(); // 同步等待完成
}

static async Task RunAsync() {
    await Task.Delay(3000);
    Console.WriteLine("Done, Done");
}

關鍵:用 GetAwaiter().GetResult() 而非 .Result 或 .Wait(),可保留原始例外堆疊,避免 AggregateException 包裹。

解法二:Lambda + 委派內建 async

static void Main(string[] args) {
    Action act = async () => {
        await Task.Delay(5000);
        Console.WriteLine("哇哈哈,哈哈哇。");
    };
    act();           // 啟動非同步
    Console.Read();  // 防止主執行緒結束
}

委派本身可標記 async,呼叫 act() 即啟動狀態機,主執行緒繼續往下跑,靠 Console.Read() 擋住結束。

解法三:C# 7.1+ 直接寫 async Main(Visual Studio 2017 15.3+ / .NET Core 2.0+)

static async Task Main(string[] args) {
    await Task.Delay(8000);
    Console.WriteLine("新大陸發現!");
}

編譯器會自動生成同步包裝器,開發者完全感知不到。

避坑指南

  • 不要 在 Main 用 .Result/.Wait() 同步等待 → 易造成死結,特別是 UI 執行緒或 ASP.NET 同步上下文。
  • 記得 在非同步啟動後,主執行緒必須有機制(Console.Read、Task.WaitAll、GetAwaiter().GetResult())等待完成,否則程式瞬間退出。
  • 回傳碼:async Task<int> Main() 可直接回傳 Exit Code,方便腳本判斷成敗。

現在,Main 也能寫出現代化的非同步程式碼了——選適合專案框架版本的姿勢,告別 Thread.Sleep 與 ManualResetEvent 的遠古時代吧。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved