以下是我在撰寫 C# Async Programming 會關注到的事項,我也是從別人的經驗學來的,也許值得參考。
// 好的做法
public async Task<int> DoSomethingAsync()
{
var result = await CallDependencyAsync();
return result + 1;
}
// 避免這樣做
public int DoSomething()
{
var result = CallDependencyAsync().Result; // 可能導致死鎖
return result + 1;
}
// 好的做法
public async Task BackgroundOperationAsync()
{
var result = await CallDependencyAsync();
DoSomething(result);
}
// 避免這樣做
public async void BackgroundOperation() // 可能導致未捕獲的異常
{
var result = await CallDependencyAsync();
DoSomething(result);
}
// 好的做法
public async Task<string> GetDataAsync()
{
var result = await FetchDataAsync();
return ProcessData(result);
}
// 避免這樣做
public string GetData()
{
var result = FetchDataAsync().Result; // 可能導致死鎖
return ProcessData(result);
}
將 CancellationToken 參數傳遞給支援的 API。
public async Task<string> DoAsyncThing(CancellationToken cancellationToken = default)
{
byte[] buffer = new byte[1024];
// 正確地將 cancellationToken 傳遞給 ReadAsync
int read = await _stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
return Encoding.UTF8.GetString(buffer, 0, read);
}
使用 async/await 提供更好的異常處理。
// 好的做法
public async Task<int> DoSomethingAsync()
{
return await CallDependencyAsync();
}
// 避免這樣做,除非有性能考慮
public Task<int> DoSomething()
{
return CallDependencyAsync();
}
沒有必要對 Task.FromResult 使用 await,因為這會增加不必要的開銷。
// 好的做法
public Task<int> GetValueAsync()
{
return Task.FromResult(42);
}
// 避免這樣做
public async Task<int> GetValueAsync()
{
return await Task.FromResult(42); // 不必要的 await
}