HttpClient
yerleşik zamanaşımı özelliğine sahiptir (tüm zaman uyumsuz olmalarına rağmen, örneğin zaman aşımları, http isteği işlevine dikey olarak düşünülebilir ve böylece genel asenkronize yardımcı programlar tarafından ele alınabilir, ancak bu bir kenara atılabilir) ve zaman aşımı başladığında TaskCanceledException
(AggregateException
numaralı ürüne sarılır) atar.Kullanıcı iptali arasındaki zaman aşımını ayırt etme
TCE, CancellationToken.None
'a eşit olan CancellationToken
içerir. Kendime ait bir CancellationToken
ile HttpClient
sağlamak ve bittiği (veya zaman aşımına) önce işlemi iptal etmek o kullanırsanız
Şimdi, bir CancellationToken.None
ile yine TaskCanceledException
aynı olsun.
yapmak zorunda kalmadan, bir zaman aşımı isteğini iptal edip anlamaya, sadece atılan istisna bakarak , hala bir yolu var mı benim kendi CancellationToken
istisna denetler koduna erişilebilir?
P.S. Bu bir hata olabilir ve CancellationToken
bir şekilde yanlış bir şekilde CancellationToken.None
'a ayarlandı mı? Özel CancellationToken kutusunu kullanarak iptal edilen 'da, TaskCanceledException.CancellationToken
özel belirtecin eşit olmasını beklerim.
Düzenleme orijinal CancellationTokenSource
erişimi olan, sorunu biraz daha açıklığa kavuşturmak için, zaman aşımı ve kullanıcı iptal ayırt etmek kolaydır: gerçek
origCancellationTokenSource.IsCancellationRequested ==
İstisnadan CancellationToken
'u almak yanlış yanıt veriyor olsa da:
((TaskCanceledException) e.InnerException) yoğun talep nedeniyle, yanlış ==
İşte minimal örnek .CancellationToken.IsCancellationRequested:
public void foo()
{
makeRequest().ContinueWith(task =>
{
try
{
var result = task.Result;
// do something with the result;
}
catch (Exception e)
{
TaskCanceledException innerException = e.InnerException as TaskCanceledException;
bool timedOut = innerException != null && innerException.CancellationToken.IsCancellationRequested == false;
// Unfortunately, the above .IsCancellationRequested
// is always false, no matter if the request was
// cancelled using CancellationTaskSource.Cancel()
// or if it timed out
}
});
}
public Task<HttpResponseMessage> makeRequest()
{
var cts = new CancellationTokenSource();
HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(10) };
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "url");
passCancellationTokenToOtherPartOfTheCode(cts);
return client.SendAsync(httpRequestMessage, cts.Token);
}
Bu davranışı sergileyen kod minimal bir parça yayınlamak edin: (güvenilir) istisna bağlı belirteci ayarlanır alamadım. –
neden istisnayı işleyen görevi başlatan kod değil?Bu kod parçası zaten CancellationToken'e sahip olmalı, bu senaryoyu yönetebilir ve sadece daha yüksek seviyeli try/catch bloğunun almasını istediğiniz istisnayı TokenSource –
@FranciscoNoriega olmadan alabilirsiniz. Bazen kodu ayırmak, ör. yeniden kullanılabilir hale getirmek için ve ayrıca senkronize olmayan kodda. Böylece, kodun tanımlandığı konumdan farklı yerlerde yakalama istisnalarını sonlandırırsınız. Etrafta yer alan bütün devletleri geçmek zorunda kalmak istemiyorum, özellikle de istisna, gerektiğinde bu durumu sağlıyor gibi görünüyor - dışında olması gerektiği gibi düşünmüyor. Onu nasıl kullandığımı gösteren soyulmuş bir örneğe bakın. –