Ogg*_*las 5 .net c# asynchronous async-await .net-core
我间歇性地得到以下例外情况:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
像这样调用:
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);
}
Run Code Online (Sandbox Code Playgroud)
该问题可能是由于套接字 耗尽造成的。这是 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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4038 次 |
| 最近记录: |