私が知る限り、それが特にタイムアウトが発生したことを知る方法はありません。適切な場所を見ていませんか、それとももっと大きなものを見逃していますか?
string baseAddress = "http://localhost:8080/";
var client = new HttpClient()
{
BaseAddress = new Uri(baseAddress),
Timeout = TimeSpan.FromMilliseconds(1)
};
try
{
var s = client.GetAsync("").Result;
}
catch(Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.InnerException.Message);
}
これは返します:
1つ以上のエラーが発生しました。
タスクがキャンセルされました。
GetAsync
メソッドを待つ必要があります。タイムアウトになった場合、TaskCanceledException
をスローします。さらに、GetStringAsync
およびGetStreamAsync
は内部的にタイムアウトを処理するため、決してスローされません。
string baseAddress = "http://localhost:8080/";
var client = new HttpClient()
{
BaseAddress = new Uri(baseAddress),
Timeout = TimeSpan.FromMilliseconds(1)
};
try
{
var s = await client.GetAsync();
}
catch(Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.InnerException.Message);
}
私は同じ問題を再現していますが、本当に迷惑です。私はこれらが便利だと感じました:
HttpClient.GetAsyncのバグはTaskCanceledExceptionではなくWebExceptionをスローする必要があります
リンクがどこにも行かない場合のコード:
var c = new HttpClient();
c.Timeout = TimeSpan.FromMilliseconds(10);
var cts = new CancellationTokenSource();
try
{
var x = await c.GetAsync("http://linqpad.net", cts.Token);
}
catch(WebException ex)
{
// handle web exception
}
catch(TaskCanceledException ex)
{
if(ex.CancellationToken == cts.Token)
{
// a real cancellation, triggered by the caller
}
else
{
// a web request timeout (possibly other things!?)
}
}
サービスコールがタイムアウトしたかどうかを判断する最善の方法は、HttpClientのタイムアウトプロパティではなくキャンセルトークンを使用することであることがわかりました。
var cts = new CancellationTokenSource();
cts.CancelAfter(timeout);
そして、サービス呼び出し中にCancellationExceptionを処理します...
catch(TaskCanceledException)
{
if(!cts.Token.IsCancellationRequested)
{
// Timed Out
}
else
{
// Cancelled for some other reason
}
}
もちろん、サービス側でタイムアウトが発生した場合、WebExceptionで処理できるはずです。
から http://msdn.Microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx
ドメインネームシステム(DNS)クエリが返されるか、タイムアウトになるまでに最大15秒かかる場合があります。リクエストに解決が必要なホスト名が含まれていて、タイムアウトを15秒未満の値に設定すると、15秒以上かかる場合がありますリクエストのタイムアウトを示すためにWebExceptionがスローされます。
次に、Status
プロパティにアクセスします。 WebExceptionStatus を参照してください
基本的に、OperationCanceledException
をキャッチし、SendAsync
(またはGetAsync
、または使用しているHttpClient
メソッドに渡されたキャンセルトークンの状態を確認する必要があります。 :
IsCancellationRequested
がtrue)、それはリクエストが本当にキャンセルされたことを意味しますもちろん、これはあまり便利ではありません...タイムアウトの場合はTimeoutException
を受け取る方が良いでしょう。ここでは、カスタムHTTPメッセージハンドラーに基づいたソリューションを提案します。 HttpClientでのタイムアウト処理の改善
_httpClient = new HttpClient(handler) {Timeout = TimeSpan.FromSeconds(5)};
私が普段やっていることは、私にとってはかなりうまくいくようです。プロキシを使用する場合は特に良いです。