Sejauh yang saya tahu, tidak ada cara untuk mengetahui bahwa ini adalah timeout khusus yang telah terjadi. Apakah saya tidak mencari di tempat yang tepat, atau saya kehilangan sesuatu yang lebih besar?
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);
}
Ini mengembalikan:
Satu atau lebih kesalahan terjadi.
Tugas dibatalkan.
c#
timeout
dotnet-httpclient
Benjol
sumber
sumber
Jawaban:
Anda harus menunggu
GetAsync
metode ini. Kemudian akan membuangTaskCanceledException
jika sudah habis. Selain itu,GetStringAsync
dan secaraGetStreamAsync
internal menangani batas waktu, sehingga mereka tidak akan pernah menyerah.sumber
GetStreamAsync
melemparkanTaskCanceledException
untuk saya.TaskCanceledException
disebabkan oleh waktu tunggu HTTP dan tidak, katakan pembatalan langsung atau alasan lain?TaskCanceledException.CancellationToken.IsCancellationRequested
. Jika salah, Anda dapat yakin itu adalah batas waktu.IsCancellationRequested
set token pengecualian pada pembatalan langsung seperti yang saya pikirkan sebelumnya: stackoverflow.com/q/29319086/62600Saya mereproduksi masalah yang sama dan itu sangat menjengkelkan. Saya menemukan ini berguna:
HttpClient - berurusan dengan pengecualian agregat
Bug di HttpClient.GetAsync harus membuang WebException, bukan TaskCanceledException
Beberapa kode jika tautannya tidak menuju ke mana-mana:
sumber
WebException
bisa ditangkap. Mungkin ini akan membantu.default(CancellationToken)
sebelum membandingkan denganex.CancellationToken
.Saya menemukan bahwa cara terbaik untuk menentukan apakah panggilan layanan telah kehabisan waktu adalah dengan menggunakan token pembatalan dan bukan properti batas waktu HttpClient:
Dan kemudian menangani PembatalanException selama panggilan layanan ...
Tentu saja jika batas waktu terjadi pada sisi layanan, itu harus dapat ditangani oleh WebException.
sumber
cts.Token.IsCancellationRequested
initrue
harus berarti bahwa batas waktu telah terjadi?Dari http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx
Anda kemudian mendapatkan akses ke
Status
properti, lihat WebExceptionStatussumber
AggregateException
denganTaskCancelledException
dalam. Saya pasti melakukan sesuatu yang salah ...catch(WebException e)
?AggregateException
itu tidak tertangani. Jika Anda membuat proyek konsol VS, tambahkan referensiSystem.Net.Http
dan masukkan kodemain
, Anda dapat melihatnya sendiri (jika Anda mau).TaskCanceledException
. Ini tampaknya dilemparkan oleh penanganan batas waktu internal TPL, pada tingkat yang lebih tinggi dariHttpWebClient
. Tampaknya tidak ada cara yang baik untuk membedakan antara pembatalan batas waktu dan pembatalan pengguna. Hasil dari ini adalah bahwa Anda mungkin tidak mendapatkanWebException
dalam AndaAggregateException
.Pada dasarnya, Anda perlu menangkap
OperationCanceledException
dan memeriksa status token pembatalan yang diteruskan keSendAsync
(atauGetAsync
, atauHttpClient
metode apa pun yang Anda gunakan):IsCancellationRequested
benar), itu berarti permintaan itu benar-benar dibatalkanTentu saja, ini sangat tidak nyaman ... akan lebih baik untuk menerima
TimeoutException
jika ada batas waktu. Saya mengusulkan solusi di sini berdasarkan penangan pesan HTTP khusus: Penanganan batas waktu yang lebih baik dengan HttpClientsumber
HttpClient.Timeout
ke tak terhingga?adalah apa yang biasanya saya lakukan, sepertinya berhasil cukup baik untuk saya, terutama baik saat menggunakan proxy.
sumber