Occasionally get System.AggregateException:

winanjaya 146 Reputation points
2022-12-04T00:58:55.98+00:00

Why I occasionally get the following exception in my HttpClient GET below:

                while(true)  
                {  
                    pageNo++;  
  
                    int iStatusCode = 0;  
  
                    HttpClientHandler clientHandler = new HttpClientHandler();  
                     
                    clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) =>  
                    {  
                        return sslPolicyErrors == SslPolicyErrors.None;  
                    };  
  
                    var client = new HttpClient(clientHandler);  
  
                    var url = new Uri($"https://xxxxxxx/ongoing_sessions/?fromStartDate={startDate}&per_page=500&page={pageNo}");  
  
                    client.DefaultRequestHeaders.Accept.Clear();  
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));  
                    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Token", token);  
                    client.Timeout = TimeSpan.FromMinutes(Models.AppSettings.Application.HTTP_MINUTES_TIMEOUT);  
  
                    var response = client.GetAsync(url).Result;  
                    HttpStatusCode statusCode = response.StatusCode;  
                    iStatusCode = (int)statusCode;  
  
                    if (statusCode == HttpStatusCode.OK)  
                    {  
                        response.EnsureSuccessStatusCode();  
                        string res = response.Content.ReadAsStringAsync().Result;  
                        if (response.IsSuccessStatusCode)  
                        {   ......  }  
                    }  
                    else  
                     {  
                         break;  
                     }  
          }  
   

Process.Get_OnGoing_SessionAsync: 8944477500001389315: System.AggregateException: One or more errors occurred. (The SSL connection could not be established, see inner exception.) ---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream. at System.Net.Security.SslStream.ReceiveBlobAsyncTIOAdapter at System.Net.Security.SslStream.ForceAuthenticationAsyncTIOAdapter at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken) --- End of inner exception stack trace --- at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(HttpRequestMessage request) at System.Threading.Tasks.TaskCompletionSourceWithCancellation1.WaitWithCancellationAsync(CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.GetHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpClient.g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken) --- End of inner exception stack trace --- at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) at System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification) at .Models.Process.Get_OnGoing_SessionAsync(Int64 tokensPid, String token, String iccid, String cdrStartDate) in Process.cs:line 516

Developer technologies ASP.NET ASP.NET Core
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. SurferOnWww 4,631 Reputation points
    2022-12-04T01:39:06.47+00:00

    Please read the "Instancing" section of the following Microsoft document:

    HttpClient Class
    https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-7.0

    "HttpClient is intended to be instantiated once and reused throughout the life of an application. In .NET Core and .NET 5+, HttpClient pools connections inside the handler instance and reuses a connection across multiple requests. If you instantiate an HttpClient class for every request, the number of sockets available under heavy loads will be exhausted. This exhaustion will result in SocketException errors."

    0 comments No comments

  2. winanjaya 146 Reputation points
    2022-12-04T01:47:45.21+00:00

    Hi @SurferOnWww

    Thank you so much for your reply, yes, I have read that, looks like I have to use a static or singleton HTTPClient, but I don't have an idea about how to do that in NET6 and how to use it on many classes?

    can you give me a simple example?
    thank you so much in advance


  3. winanjaya 146 Reputation points
    2022-12-04T03:24:05.417+00:00

    What I have tried the following:

    program.cs

     builder.Services.AddHttpClient<ITest, Test>(c =>  
     {  
         c.BaseAddress = new Uri("https://iot.test.com/api");  
          c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));  
         c.Timeout = TimeSpan.FromMinutes(20);  
     });  
    

    Test.cs

    public interface ITest  
    {  
        Task TestAsync();  
    }  
      
    
    public class Test:ITest  
    {  
        private HttpClient _httpClient;  
    
        public Test(HttpClient httpClient, string token)  
        {  
            _httpClient = httpClient;  
            _httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Token", token);  
        }  
    
    
        public async Task TestAsync()  
        {  
            int page = 0;  
            while (true)  
            {  
                page++;  
    
                var url = new Uri($"https://iot.test.com/api/v2.2/sims/?per_page=500&page={page}");  
    
                var response = _httpClient.GetAsync(url).Result;  
                HttpStatusCode statusCode = response.StatusCode;  
    
                if (statusCode == HttpStatusCode.OK)  
                {  
                    response.EnsureSuccessStatusCode();  
                    string res = response.Content.ReadAsStringAsync().Result;  
                    if (response.IsSuccessStatusCode)  
                    {  
                        ....  
                    }  
                }  
                else  
                {  
                    break;  
                }  
            }  
        }  
    

    and I call it using:

            HttpClientHandler clientHandler = new HttpClientHandler();  
            clientHandler.SslProtocols = System.Security.Authentication.SslProtocols.Tls13;  
            clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) =>  
            {  
                return sslPolicyErrors == SslPolicyErrors.None;  
            };  
    
            Models.Test tp = new Test(new HttpClient(clientHandler), "XxXxXx");  
            tp.TestAsync();  
    
    • Did I place the HttpClientHandler correctly?
    • Is there any other better approach for doing this?

    many thanks in advance


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.