У меня есть следующий код для проверки доступности приложений из play market и app store:
public async Task<List<CheckPackageResponse>> CheckAsync(List<string> appIds)
{
var sem = new SemaphoreSlim(200);
var tasks = appIds.Select(async (a, i) =>
{
await sem.WaitAsync();
var response = new CheckPackageResponse
{
AppId = a,
};
string url;
// if IOS
if (a.All(Char.IsDigit))
{
url = $"https://apps.apple.com/ru/app/id{a}?dataOnly=true&isWebExpV2=true";
}
else
{
url = $"https://play.google.com/store/apps/details?id={a}";
}
try
{
_client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36");
var resp = await _client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
response.HttpStatus = (int) resp.StatusCode;
return response;
}
catch (Exception e)
{
response.ErrorMessage = e.Message;
response.StackTrace = e.StackTrace;
return response;
}
finally
{
sem.Release();
}
}).ToList();
return (await Task.WhenAll(tasks)).ToList();
}
А в Startup.cs
у меня есть следующее, чтобы ввести HttpClient
:
services.AddHttpClient<ICheckPackagesService, CheckPackagesService>(x =>
{
x.Timeout = TimeSpan.FromSeconds(7);
}).ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
{
Proxy = new WebProxy(Configuration["Proxy"] != "" ? Configuration["Proxy"] : null)
});
Работает хорошо. Я могу дать список идентификаторов приложений, и API ответит мне, доступно приложение или нет. Но это имеет некоторые проблемы. Через некоторое время произошел сбой с ошибкой
Используемый адрес.
Это говорит мне, что HTTP-клиент не закрывает соединения. Но я знаю, что эта проблема возможна, если я использую что-то вроде этого:
using(var http = new HttpClient(...)) {
...
}
И это определенно не мой случай. Так что не так в моем случае? Где ошибка?
Обновление
Я прикреплю здесь свою трассировку стека
в System.Net.Http.ConnectHelper.ConnectAsync (хост строки, порт Int32, CancellationToken cancellationToken) \n в System.Threading.Tasks.ValueTask 1.get_Result()\n at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)\n at System.Threading.Tasks.ValueTask
1.get_Result () \ n в System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync (ValueTask 1 creationTask)\n at System.Threading.Tasks.ValueTask
1.get_Result () \ n в System.Net.Http.ottp. SendWithRetryAsync (запрос HttpRequestMessage, Boolean doRequestAuth, CancellationToken cancellationToken) \ n в System.Net.Http.RedirectHandler.SendAsync (запрос HttpRequestMessage, CancellationTokationHoking.Hegn.Tegn.Exe) \ n в Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync (запрос HttpRequestMessage, CancellationToken cancellationToken) \ n в System.Net.Http.HttpClient.FinishSendAsyncUnttaskRequest1, запрос на передачу запроса HUQllationTokenSource cts, Boolean disposeCts) \ n в ApChecker.Services.Concrete.CheckPackagesService. <> c__DisplayClass2_0. d.MoveNext () в /builds/mobilemediaru/makeapp/apchecker/ApChecker/Services/Concrete/CheckPackagesService.cs:line 50