はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】HttpClient.GetStringAsyncにCancellationTokenを引数で渡せないので対策を考える

はじめに

タイトルの通りUnityでHttpClient.GetStringAsyncCancellationTokenを引数で渡そうと思ったのですが、どうやらバージョンが違うせいでできないみたいでした。

公式ドキュメントを見てみると.NET 5.0のみ対応らしいです。

public System.Threading.Tasks.Task<string> GetStringAsync (Uri? requestUri, System.Threading.CancellationToken cancellationToken);

これはどうしたものか考えていたのですが、一応2つほど解決策を考えたので紹介をしたいと思います。

解決策1

public static class HttpClientWrapper
{
    private static HttpClient _client = new HttpClient();

    public static async UniTask<string> GetStringAsync(string uri, CancellationToken token)
    {
        var response = await _client.GetStringAsync(uri);
        token.ThrowIfCancellationRequested();
        return response;
    }
}

最初に思いついた方法は,GetStringAsyncをした後にCancellationToken.ThrowIfCancellationRequestedメソッドを呼ぶやり方です。
CancellationToken.ThrowIfCancellationRequested メソッド (System.Threading) | Microsoft Docs

ただしこの方法だとキャンセルが呼ばれても通信が終わるまで待ち,キャンセルが行われます。

永遠に通信が終わらないなんてことがないように,タイムアウト処理はつけておきましょう。

public static class HttpClientWrapper
{
    private static HttpClient _client = new HttpClient();

    public static async UniTask<string> GetStringAsync(string uri, TimeSpan timeout, CancellationToken token)
    {
        _client.Timeout = timeout;
        var response = await _client.GetStringAsync(uri);
        token.ThrowIfCancellationRequested();
        return response;
    }
}

解決策2

次の解決策はHttpClient.GetAsyncを使うパターンです。
HttpClient.GetAsync メソッド (System.Net.Http) | Microsoft Docs

HttpClient.GetAsyncメソッドは引数でCancellationTokenを渡せるみたいでした。

public static class HttpClientWrapper
{
    private static HttpClient _client = new HttpClient();

    public static async UniTask<string> GetStringAsync(string uri, TimeSpan timeout, CancellationToken token)
    {
        _client.Timeout = timeout;
        var response = await _client.GetAsync(uri, token);
        return await response.Content.ReadAsStringAsync();
    }
}


少し回りくどいですが、こちらの場合はキャンセルされたときに通信も止めることができるはずです。