3

HttpClient呼び出しのデフォルトのタイムアウトを5秒に設定しようとしています。HttpClientのキャンセルで、基になるTCP呼び出しが終了しない

これはCancellationTokenSourceで行っています。

ここでは、コードの該当ビットがあります:私は、呼び出し元のコードの面で期待通り

var cancellationToken = new CancellationTokenSource(); 
cancellationToken.CancelAfter(TimeSpan.FromSeconds(5)); 
var result = _httpClient.SendAsync(request, cancellationToken.Token); 

作品は(私は.NET 4.7のコンソールアプリでテスト)エラーを「タスクはキャンセルされました」、しかし、私ばかりそれが最終的にあきらめたまで要求はまだ、1分間走っていたフィドラーに気づい:

enter image description here

誰かがこの動作を説明できますか?

キャンセルが発生すると、基本となるリクエストもキャンセルされることになります。私はTimeout設定があります知っているが、私はそれまたはキャンセルトークンを使用する必要があるかどうかわからないnew HttpClient { BaseAddress = baseAddress }

_httpClientが同じようにインスタンス化されますか?私の推測はTimeoutですが、非同期/待望のケースですか?

+3

HTTP 1.1では、接続の全部を切断することなく、「このリクエストをキャンセルする」アクションはありません.HeepClientがキープアライブ/接続の再利用をサポートするために行っていないと思います。 –

+0

@Damien_The_Unbelieverああ...もちろん..「Keep-Alive」を完全に忘れてしまった。あなたは、HTTPクライアントで 'Keep-Alive'をfalseに設定することができます(デフォルトは真です、正当な理由のため、確かです) – RPM1984

+1

@Damien_The_Unbelieverしかし、それは、基本的な_request_(接続ではなく_request_)キャンセルトークンのポイントは何ですか?クライアント(ブラウザ、または私のコンソールアプリケーションで)をもう結果に気にしないでください。 (しかしリクエストはまだバックグラウンドで実行されているかもしれません) – RPM1984

答えて

1

Damienがコメントで述べたように、HttpClientは可能な限り接続を再利用するため、キャンセル時に接続が閉じられない理由があります。

このようなリクエストをキャンセルすると、HttpClientは相手側との間でデータの送受信を停止するだけです。それはキャンセルされたことを相手に知らせるために何も送信しません。したがって、1分のタイムアウトは、接続の相手側の動作によって異なります。

また、5秒後に各要求をキャンセルする場合は、_httpClientというプロパティをTimeSpan.FromSeconds(5)に設定することもできます。振る舞いはまったく同じです(反対側が5秒以内に応答しない場合はTaskCanceledExceptionがスローされます)。

関連する問題