【踩坑】.NET非同步方法不標記async,Task<int> 返回值 return default問題

欲東發表於2023-04-25

        在.NET中,返回型別為 Task<T> 的方法並不一定要標記為 async。這是因為 async 關鍵字只是用來告訴編譯器該方法中包含非同步操作,並且可以使用 await 和其他非同步特性(如 Task.WhenAll)來等待非同步操作完成。

如果一個方法中沒有使用 await 或者其他非同步特性,但是返回型別為 Task<T>,那麼該方法仍然是非同步方法。它返回的任務(Task<T>)表示一項非同步操作,可以被等待。

例如,以下示例中的 DoSomethingAsync 方法返回一個 Task<int> 物件,但是沒有使用 async 關鍵字:
 

public Task<int> DoSomethingAsync()
{
    return Task.Run(() =>
    {
        // 在此方法中執行一些非同步操作,例如讀寫檔案、呼叫Web服務等。
        // 這裡使用 Task.Run 來模擬一些耗時的操作。
        Thread.Sleep(TimeSpan.FromSeconds(1)); // 睡眠1秒鐘
        return 42; // 返回非同步操作的結果
    });
}
【踩坑】.NET非同步方法不標記async,Task<int> 返回值 return default問題

        在上述示例中,DoSomethingAsync 方法使用 Task.Run 來開啟一個新的執行緒執行非同步操作,然後返回結果。雖然該方法沒有標記為 async,但是它返回的 Task<int> 物件同樣可以使用 await 關鍵字等待非同步操作完成。例如:

int result = await DoSomethingAsync();
【踩坑】.NET非同步方法不標記async,Task<int> 返回值 return default問題

        在呼叫 DoSomethingAsync 方法時,返回的 Task<int> 物件表示一項非同步操作,可以使用 await 關鍵字等待操作完成。因此,即便方法沒有標記為 async,它仍然屬於非同步方法。

 

坑點

        public Task<int> DoSomethingAsync()
        {
            return default;
        }
【踩坑】.NET非同步方法不標記async,Task<int> 返回值 return default問題

        由於返回Task<int>的非同步方法程式碼,可以透過客戶程式碼await等待非同步方法結果,可以直接拿到T的結果。而如果非同步方法裡直接return default相當於是返回了null而不是一個Task<int> 也就無法等待了。await null就會報錯。IDE對於此類問題並沒有給出友好的警告或者提示。

 

解決方案

        將方法返回型別從 Task<int?> 改為 Task<Result<int>>,其中 Result<T> 是自定義的一個類,用於表示非同步操作的執行結果。具體實現如下:

        public Task<int> DoAsync()
        {
            return default;
        }

        public async Task<Result<int>> DoSomethingAsync()
        {
            string msg = string.Empty;
            if (string.IsNullOrWhiteSpace(msg))
            {
                return Result<int>.Fail("錯誤提示.");
            }
            var count = await DoAsync();

            return Result<int>.Success(count ?? 0);
        }
【踩坑】.NET非同步方法不標記async,Task<int> 返回值 return default問題

呼叫該方法時,需要檢查 Result 物件的 IsSuccess 屬性,以判斷該非同步操作是否成功。如果成功,則可以使用 Value 屬性獲取查詢結果。否則,可以使用 Message 屬性獲取錯誤資訊。

相關文章