在 Web 開發中,經常會遇到這樣的場景:用戶發起一個請求,Web 服務器執行一些計算密集型的操作,等待結果返回給用戶。這種情況下,如果用戶在等待結果的過程中取消了請求,那么服務器端依然會繼續執行計算,這樣就會造成資源浪費。
為了解決這個問題,我們可以使用 CancellationToken 來提高 Web 性能。CancellationToken 是 .NET 中一個很重要的概念,它可以用于在代碼執行過程中取消操作。
下面,我們將通過一個示例來演示如何使用 CancellationToken 來提高 Web 性能。
代碼示例
下面是一段使用 CancellationToken 的代碼:
public?async?Task<int>?DoWorkAsync(CancellationToken?cancellationToken)
{var?result?=?0;for?(int?i?=?0;?i?<?10000;?i++){//?檢查是否已經取消操作cancellationToken.ThrowIfCancellationRequested();result?+=?i;}return?result;
}
上面的代碼定義了一個 DoWorkAsync 方法,該方法用于執行一個計算密集型的任務。在方法內部,我們使用了 CancellationToken 的 ThrowIfCancellationRequested 方法來檢查是否已經取消了操作。如果取消了操作,那么方法會拋出一個 OperationCanceledException 異常,并終止執行。
這樣,我們就可以在 Web 服務器端執行計算密集型的任務時,在用戶取消請求時及時停止執行,避免浪費資源。
使用建議
在實際開發中,我們可以將 CancellationToken 作為一個參數,傳遞給執行計算密集型任務的方法。例如,在 ASP.NET Core 中,我們可以在控制器的 Action 方法中加入一個 CancellationToken 參數,然后在執行計算任務時傳遞這個參數。
[HttpGet]
public?async?Task<IActionResult>?GetData(CancellationToken?cancellationToken)
{var?result?=?await?GetDataAsync(cancellationToken);return?Ok(result);
}
下面是一段演示了 cancellationToken 在 service 層和數據庫訪問層的使用方式的代碼:
//?service?層
public?async?Task<int>?GetDataAsync(CancellationToken?cancellationToken)
{//?執行計算密集型的任務var?result?=?await?DoWorkAsync(cancellationToken);//?訪問數據庫using?(var?dbContext?=?new?DbContext()){return?await?dbContext.SaveChangesAsync(cancellationToken);}
}
上面的代碼定義了一個 service 層的 GetDataAsync 方法,該方法用于從數據庫中獲取數據。在方法中,我們首先執行了一個計算密集型的任務,然后使用了 DbContext 的 CountAsync 方法來從數據庫中獲取數據。
在使用 cancellationToken 的過程中,我們首先在 GetDataAsync 方法的參數列表中加入了一個 CancellationToken 類型的參數。這樣,我們就可以在調用該方法時傳入一個 cancellationToken 參數,并在方法中使用它來檢查是否取消了操作。
在方法中,我們首先執行了一個計算密集型的任務,并將 cancellationToken 作為參數傳遞給了 DoWorkAsync 方法。如果在執行過程中用戶取消了操作,那么 DoWorkAsync 方法會拋出一個 OperationCanceledException 異常,并終止執行。
然后,我們使用 DbContext 的 SaveChangesAsync 方法來從數據庫中獲取數據。在調用 SaveChangesAsync 方法時,我們也將 cancellationToken 作為參數傳遞進去。如果用戶取消了操作,那么 SaveChangesAsync 方法也會拋出一個 OperationCanceledException 異常,并停止執行。
總結
通過使用 CancellationToken,我們可以在用戶取消請求時,及時停止執行的任務,避免浪費資源。
參考資料
CancellationToken
DbContext.SaveChangesAsync
本文采用 Chat OpenAI 輔助注水澆筑而成,如有雷同,完全有可能。