[英]Exception using await HttpClient.GetAsync in Portable Class Library
[英]HttpClient not throwing exception when using await on GetAsync
我正在使用以下代碼獲取端點並將其寫入緩存:
public async Task UpdateCacheFromHttp(string Uri)
{
if (string.IsNullOrEmpty(Uri))
return;
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(Uri);
if ((response != null) && (response.IsSuccessStatusCode))
{
var responseStream = await response.Content.ReadAsStreamAsync();
WriteToCache(responseStream);
}
}
代碼在 IIS 上運行。
如果無法到達端點,我希望 GetAsync 拋出異常。 即使使用 Try-Catch,它似乎也永遠不會失敗。 GetAsync 永遠不會返回(我在 HttpClient 上嘗試了 5 秒超時,但仍然沒有返回)。
這確實會引發異常:
public Task UpdateCacheFromHttp(string Uri)
{
var updateCacheTask = Task.Factory.StartNew(new Action(() =>
{
if (string.IsNullOrEmpty(Uri))
return;
var httpClient = new HttpClient();
var response = httpClient.GetAsync(Uri).Result;
if (response.IsSuccessStatusCode)
{
var responseStream = response.Content.ReadAsStreamAsync().Result;
WriteToCache(responseStream);
}
}));
return updateCacheTask;
}
我得到預期的“無法連接到遠程服務器”。
我懷疑它與在 IIS 中運行的代碼有關,但為什么呢? 如何在不需要開始新任務的情況下正確拋出異常?
我的直覺告訴我,你正在調用Wait
或Result
進一步調用你的調用堆棧。
如果這是正確的,那么您將導致僵局,正如我在我的博客中所解釋的那樣。
由於我遇到了沒有拋出異常的相同行為,我創建了一個示例來演示該問題的可能解決方案:
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace Exam
{
public static class Program
{
private static async Task<string> GetWebPage(string uri)
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(new Uri(uri, UriKind.Absolute), HttpCompletionOption.ResponseContentRead);
return await response.Content.ReadAsStringAsync();
}
public static void Main(string[] args)
{
try
{
// These two lines do not work - i.e. it terminates the application without any exception being thrown...
//string s = await GetWebPage(@"https://www.dwd.de/DE/leistungen/klimadatendeutschland/klimadatendeutschland.html");
//Console.WriteLine(s);
// This works:
Task<string> getPageTask = GetWebPage(@"https://www.dwd.de/DE/leistungen/klimadatendeutschland/klimadatendeutschland.html");
getPageTask.Wait();
if (getPageTask.IsCompleted)
Console.WriteLine(getPageTask.Result);
}
catch (AggregateException aex)
{
aex.InnerExceptions.AsParallel().ForAll(ex => Console.WriteLine(ex));
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadKey();
}
}
}
當您另外將 URI 更改為 @"invalid https://...." 之類的內容時,您將檢索 AggregateException。 希望,它可以幫助任何人:-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.