c# - .NET Core 3.1 HttpClient 间歇性抛出异常:SocketException: I/O 操作已被中止,因为线程退出或
问题描述
我间歇性地得到以下例外:
IOException:无法从传输连接读取数据:I/O 操作已因线程退出或应用程序请求而中止。
SocketException:由于线程退出或应用程序请求,I/O 操作已中止。
系统正在查询外部资源,并且不时发生异常,但似乎没有任何异常。我试图设置更长的超时时间,HttpClient
但没有帮助。在异常发生之前,它可能是 5000-50000 次搜索,但我仍然想减轻它。如果我在出现异常后直接重试相同的搜索,它会起作用,因此即使我无法访问该应用程序日志,接收方似乎也没有问题。上运行.NET Core 3.1
。
我的服务.cs
public class MyService
{
private readonly HttpClient _httpClient;
public MyService(HttpClient client)
{
client.BaseAddress = new Uri("https://example.com/");
client.Timeout = TimeSpan.FromMinutes(5);
_httpClient = client;
}
private async Task<List<string>> GetValuesFromSearch(string search)
{
//Exception is thrown here
var response = await _httpClient.GetAsync("search/" + search);
using var responseStream = await response.Content.ReadAsStreamAsync();
response.EnsureSuccessStatusCode();
var searchResultList = await JsonSerializer.DeserializeAsync
<List<string>>(responseStream);
return searchResultList;
}
}
像这样调用:
var myService = new MyService(new HttpClient());
foreach (var search in listToIterate)
{
//Can be called up to 200 000 times
var result = await myService.GetValuesFromSearch(search);
}
解决方案
该问题可能是由于套接字 耗尽。这是 HttpClient 的一个已知问题,解决方案是使用 HttpClientFactory。我没有对此进行测试,但这里是您的 MyService 类的快速重写:
public class MyService
{
private readonly IHttpClientFactory _httpClientFactory;
public MyService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory ??
throw new ArgumentNullException(nameof(httpClientFactory));
}
private async Task<List<string>> GetValuesFromSearch(string search)
{
var _httpClient = _httpClientFactory.CreateClient("MyClient");
_httpClient.BaseAddress = new Uri("https://example.com/");
_httpClient.Timeout = TimeSpan.FromMinutes(5);
// You could also set the above in Startup.cs or wherever you add your services:
//services.AddHttpClient("MyClient", c => {
// c.BaseAddress = new Uri("https://example.com/");
// c.Timeout = TimeSpan.FromMinutes(5);
//});
//Exception is thrown here
var response = await _httpClient.GetAsync("search/" + search);
using var responseStream = await response.Content.ReadAsStreamAsync();
response.EnsureSuccessStatusCode();
var searchResultList = await JsonSerializer.DeserializeAsync
<List<string>>(responseStream);
return searchResultList;
}
}
推荐阅读
- corda - 如何定制 Corda 医院?
- dart - Dart 中的神秘匿名函数
- python - 如何在 Python 3 中搜索并获取具有两个搜索词的字符串中的第二个词?
- c# - .NET Core API 抛出 Autofac.Core.DependencyResolutionException
- python - 数据集的学习曲线
- java - 如何使用 textwatcher 获取警察号码
- javascript - 如何在Javascript中制作平方数
- javascript - 每当我在反应应用程序中添加过滤器功能时面临的问题
- python - 指定游戏结束文本功能时出错
- reactjs - React Js如何在更改后更新状态?使用 componentDidUpdate?