通過 CancellationToken 提高 Web 效能

2022-12-15 12:01:03

在 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,我們可以在使用者取消請求時,及時停止執行的任務,避免浪費資源。

參考資料

本文采用 Chat OpenAI 輔助注水澆築而成,如有雷同,完全有可能。