dotnet / android

.NET for Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#
MIT License
1.93k stars 528 forks source link

HttpClient ObjectDisposed after SDK upgrade from 34.0.95 -> 34.0.113 #9039

Open haavamoa opened 4 months ago

haavamoa commented 4 months ago

Android framework version

net8.0-android

Affected platform version

Android SDK 34.0.113

Description

Hello, and thank you for this amazing project.

We have a mobile application running MAUI in hospitals in Norway, where Android is one of the most used platforms. We needed to deliver a new version this week. Last Wednesday / Thursday we noticed that we started getting sporadic http client disposal messages. After some time we figured out that the only changes to the app was the Android SDK version delivered by .NET . 34.0.113 was released, and we noticed that pinning to 34.0.95 fixed the issues.

After a lot of times, I've actually not been able to give you a reproducible project , and due to internal policies in my company I am unable to share my project.

But I can give you a brief explanation of the architecture surrounding http client in the project:

  1. We reuse our HttpClients as much as we can in between different pages.
  2. We add our own DelegatingHandlers to make sure we add ticket, add logging etc.
  3. We use Polly for timeouts.

The times I often see it is when I navigate between two pages that is using the same http client, but is using it against different request urls.

Here is the exception we keep seeing:

ObjectDisposed_Generic
ObjectDisposed_ObjectName_Name, Java.IO.InputStreamInvoker
System.ObjectDisposedException: ObjectDisposed_Generic
ObjectDisposed_ObjectName_Name, Java.IO.InputStreamInvoker
   at Java.Interop.JniPeerMembers.AssertSelf(IJavaPeerable )
   at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualVoidMethod(String , IJavaPeerable , JniArgumentValue* )
   at Java.IO.InputStream.Close()
   at Android.Runtime.InputStreamInvoker.Close()
   at System.IO.Stream.Dispose()
   at System.IO.BufferedStream.Dispose(Boolean )
   at System.IO.Stream.Close()
   at System.IO.Stream.Dispose()
   at System.Net.Http.StreamContent.Dispose(Boolean )
   at System.Net.Http.HttpContent.Dispose()
   at System.Net.Http.HttpResponseMessage.Dispose(Boolean )
   at Xamarin.Android.Net.AndroidHttpResponseMessage.Dispose(Boolean )
   at System.Net.Http.HttpResponseMessage.Dispose()
   at System.Net.Http.HttpClient.HandleFailure(Exception , Boolean , HttpResponseMessage , CancellationTokenSource , CancellationToken , CancellationTokenSource )
   at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage , HttpCompletionOption , CancellationTokenSource , Boolean , CancellationTokenSource , CancellationToken )

I understand that this a long shot as I do not have a reproducible project, but I hope that anyone in the team / community can reach out and see if they might have broken something, or have an idea on what we are potentially doing wrong.

Appreciate your time!

Steps to Reproduce

None unfortunately.

Did you find any workaround?

For now, we pin the SDK version by using the rollback feature of dotnet workload install, which saved our delivery, but we plan to upgrade every bits and pieces soon, so this will soon be an issue for us again.

Relevant log output

No response

simonrozsival commented 1 month ago

@Digifais what version of the .NET Android SDK are you using? Do you get this exception with the latest 34.0.138?

Digifais commented 1 month ago

@simonrozsival I was on 34.0.113, I've updated to 34.0.138 now and the exception still occurs.

Brosten commented 1 month ago

We had the same issue and ended up implementing the http client as a singelton. It solved the issue for us.

zwikk commented 1 month ago

I'm running into this issue as well and desperately looking for a solution or workaround. Implementing the http client as a singleton seems to work, but I want to avoid rewriting my implementation as much as possible.

Also can't simply replace the native AndroidMessageHandler since our certificate pinning implementation relies on it.

Wondering whether IHttpClientBuilder.SetHandlerLifetime(Timeout.InfiniteTimeSpan) would do the trick as well?

simonrozsival commented 1 month ago

@zwikk would you able to share a repro project?

Also can't simply replace the native AndroidMessageHandler since our certificate pinning implementation relies on it.

How do you implement certificate pinning? Are you using network_security_config.xml or via custom validation callback? If you're using the custom validation callback, it should also work with the managed handler.

zwikk commented 1 month ago

I don't have a repro project and also can't reproduce myself in our app. Exception logging reveal that our customers do experience the ObjectDisposedException in our app in production.

The exception seems to occur exclusively with a single HTTP POST where we ignore the response.

Cert pinning: we're implementing Javax.Net.Ssl.IHostnameVerifier and overriding GetSSLHostnameVerifier

public class MyAndroidMessageHandler : AndroidMessageHandler
{
    protected override IHostnameVerifier GetSSLHostnameVerifier(HttpsURLConnection connection)
    {
        return new CertificatePinningHostnameVerifier();
    }
}

We're using Refit, Polly and HttpClientFactory, a bunch of custom MessageHandlers, including the custom AndroidMessageHandler for cert pinning purposes.

ederbond commented 1 month ago

I'm still getting it randomly, but very often on my .NET MAUI app.

image

This is how my .MAUI app .csproj looks like image

This is my workload list

Installed Workload Id      Manifest Version       Installation Source
---------------------------------------------------------------------
maui-windows               8.0.82/8.0.100         VS 17.11.35312.102
maccatalyst                17.5.8030/8.0.100      VS 17.11.35312.102
ios                        17.5.8030/8.0.100      VS 17.11.35312.102
android                    34.0.113/8.0.100       VS 17.11.35312.102
aspire                     8.1.0/8.0.100          VS 17.11.35312.102

And this is the stacktrace when the error occurs.

   at Java.Interop.JniPeerMembers.AssertSelf(IJavaPeerable self) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.cs:line 153
   at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualVoidMethod(String encodedMember, IJavaPeerable self, JniArgumentValue* parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs:line 57
   at Java.IO.InputStream.Close() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Java.IO.InputStream.cs:line 116
   at Android.Runtime.InputStreamInvoker.Close() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/InputStreamInvoker.cs:line 62
   at System.IO.Stream.Dispose()
   at System.IO.BufferedStream.Dispose(Boolean disposing)
   at System.IO.Stream.Close()
   at System.IO.Stream.Dispose()
   at System.IO.DelegatingStream.Dispose(Boolean disposing)
   at System.IO.Stream.Close()
   at System.IO.Stream.Dispose()
   at System.Net.Http.Json.HttpContentJsonExtensions.<ReadFromJsonAsyncCore>d__12`1[[System.Collections.Generic.IEnumerable`1[[Doc.Model.User.UserRoleSelection, Doc.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
   at Refit.SystemTextJsonContentSerializer.<FromHttpContentAsync>d__4`1[[System.Collections.Generic.IEnumerable`1[[Doc.Model.User.UserRoleSelection, Doc.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext() in c:\temp\releaser\refit\Refit\SystemTextJsonContentSerializer.cs:line 48
   at Refit.RequestBuilderImplementation.<DeserializeContentAsync>d__16`1[[System.Collections.Generic.IEnumerable`1[[Doc.Model.User.UserRoleSelection, Doc.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext() in c:\temp\releaser\refit\Refit\RequestBuilderImplementation.cs:line 450
   at Refit.RequestBuilderImplementation.<>c__DisplayClass15_0`2.<<BuildCancellableTaskFuncForMethod>b__0>d[[System.Collections.Generic.IEnumerable`1[[Doc.Model.User.UserRoleSelection, Doc.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Collections.Generic.IEnumerable`1[[Doc.Model.User.UserRoleSelection, Doc.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext() in c:\temp\releaser\refit\Refit\RequestBuilderImplementation.cs:line 385

@jonathanpeppers any news or hint about how to workaround it?

jonathanpeppers commented 1 month ago

@ederbond you aren't using the latest Android release:

You can install the VS 17.12 Preview, and just target .NET 8 instead of .NET 9 to try it.

We were thinking this might improve things:

Digifais commented 1 month ago

@ederbond you aren't using the latest Android release:

You can install the VS 17.12 Preview, and just target .NET 8 instead of .NET 9 to try it.

We were thinking this might improve things:

@jonathanpeppers, it's still occurring for me on 34.0.138

jonathanpeppers commented 1 month ago

@Digifais is the stack trace different? As you should not get a ObjectDisposedException any longer?

LaBoss commented 1 month ago

After updating to .138, the exception occurred again, but I think the stack is different

Object name: 'Java.IO.InputStreamInvoker'.
   at Java.Interop.JniPeerMembers.AssertSelf(IJavaPeerable self) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.cs:line 153
   at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualInt32Method(String encodedMember, IJavaPeerable self, JniArgumentValue* parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs:line 502
   at Java.IO.InputStream.Read(Byte[] b, Int32 off, Int32 len) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Java.IO.InputStream.cs:line 247
   at Android.Runtime.InputStreamInvoker.Read(Byte[] buffer, Int32 offset, Int32 count) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/InputStreamInvoker.cs:line 87
   at System.IO.BufferedStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.DelegatingStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.StreamReader.ReadBuffer(Span`1 userBuffer, Boolean& readToUserBuffer)
   at System.IO.StreamReader.ReadSpan(Span`1 buffer)
   at System.IO.StreamReader.Read(Char[] buffer, Int32 index, Int32 count)
   at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append, Int32 charsRequired)
   at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append)
   at Newtonsoft.Json.JsonTextReader.ParseValue()
   at Newtonsoft.Json.JsonTextReader.Read()
   at Newtonsoft.Json.JsonReader.ReadAndMoveToContent()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize[IList`1](JsonReader reader)
   at App.Extensions.SerializeExtensions.FromJson[IList`1](Stream Data)
   at App.API.Fact.Client.Clients.<_processResponse>d__81`1[[System.Collections.Generic.IList`1[[App.API.Fact.Client.Entities.Service, App.API.Fact.Client, Version=1.2407.1.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext() in D:\Mobile\App\deps\App.API.Client\src\Clients.cs:line 376
   at App.API.Fact.Client.Services.Find(String Company, ServiceFind Terms) in D:\Mobile\App\deps\App.API.Client\src\Services.cs:line 121}
    base: {System.InvalidOperationException}
    Message: "Cannot access a disposed object.\nObject name: 'Java.IO.InputStreamInvoker'."
    ObjectName: "Java.IO.InputStreamInvoker"
dotnet workload list

Installed Workload Id      Manifest Version       Installation Source
---------------------------------------------------------------------------------
android                    34.0.138/8.0.100       SDK 8.0.400, VS 17.11.35312.102
aspire                     8.2.0/8.0.100          SDK 8.0.400, VS 17.11.35312.102
ios                        17.5.8030/8.0.100      SDK 8.0.400, VS 17.11.35312.102
maccatalyst                17.5.8030/8.0.100      SDK 8.0.400, VS 17.11.35312.102
macos                      14.5.8030/8.0.100      SDK 8.0.400, VS 17.11.35312.102
maui-windows               8.0.82/8.0.100         SDK 8.0.400, VS 17.11.35312.102
tvos                       17.5.8030/8.0.100      SDK 8.0.400, VS 17.11.35312.102

Use `dotnet workload search` to find additional workloads to install.
Digifais commented 1 month ago

Also running into this after migrating from XA to .NET for Android, will see if I can set up a repro later today or over the weekend.

Stack trace:

System.Net.Http.HttpRequestException: Error while copying content to a stream.
 ---> System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Java.IO.InputStreamInvoker'.
   at Java.Interop.JniPeerMembers.AssertSelf(IJavaPeerable self) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.cs:line 153
   at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualInt32Method(String encodedMember, IJavaPeerable self, JniArgumentValue* parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs:line 502
   at Java.IO.InputStream.Read(Byte[] b, Int32 off, Int32 len) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Java.IO.InputStream.cs:line 247
   at Android.Runtime.InputStreamInvoker.Read(Byte[] buffer, Int32 offset, Int32 count) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/InputStreamInvoker.cs:line 89
   at System.IO.Stream.<>c.<BeginReadInternal>b__38_0(Object <p0>)
   at System.Threading.Tasks.Task`1[[System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__281_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at System.IO.Stream.<CopyToAsync>g__Core|27_0(Stream source, Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
   at System.IO.BufferedStream.CopyToAsyncCore(Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
   at System.Net.Http.StreamToStreamCopy.<CopyAsync>g__DisposeSourceAsync|1_0(Task copyTask, Stream source)
   at System.Net.Http.HttpContent.LoadIntoBufferAsyncCore(Task serializeToStreamTask, MemoryStream tempBuffer)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpContent.LoadIntoBufferAsyncCore(Task serializeToStreamTask, MemoryStream tempBuffer)
   at System.Net.Http.HttpContent.<WaitAndReturnAsync>d__82`2[[System.Net.Http.HttpContent, System.Net.Http, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
   at xxx.Api.WebServiceDelegationHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in /xxx.Api/Services/WebServiceDelegationHandler.cs:line 128

@jonathanpeppers The stack trace is identical as in my reply above on 34.0.138

DavidNolc commented 3 weeks ago

If this works for someone, i found a workaround using Polly, i just added this Policy .Handle<ApiException>(ex => ex.StatusCode == HttpStatusCode.OK) .WaitAndRetryAsync(RETRIES, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); o our policies and even if fails will retry and it ends working.

I also use Polly with Refit.

ederbond commented 1 week ago

Hi @jonathanpeppers I've run a dotnet workload update (not installed the VS Preview cause my Surface Laptop has just 512 GB and it's packed with other stuffs). And now I have the following workload installed but I'm still facing the same issue: This bug is a major blocking issue that's preventing all of us to ship MAUI based apps to production. Any ETA to fix it or a workaround in the meantime?

cc: @davidortinau @StephaneDelcroix @rmarinho @mattleibow @PureWeen @jsuarezruiz @Redth

Installed Workload Id      Manifest Version       Installation Source
-------------------------------------------------------------------------------
android                    34.0.143/8.0.100       SDK 8.0.400, VS 17.11.35327.3
aspire                     8.2.1/8.0.100          SDK 8.0.400, VS 17.11.35327.3
ios                        18.0.8303/8.0.100      SDK 8.0.400, VS 17.11.35327.3
maccatalyst                18.0.8303/8.0.100      SDK 8.0.400, VS 17.11.35327.3
maui-windows               8.0.82/8.0.100         SDK 8.0.400, VS 17.11.35327.3

Stacktrace

Refit.ApiException: An error occured deserializing the response.
 ---> System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Java.IO.InputStreamInvoker'.
   at Java.Interop.JniPeerMembers.AssertSelf(IJavaPeerable self) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.cs:line 153
   at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualInt32Method(String encodedMember, IJavaPeerable self, JniArgumentValue* parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs:line 502
   at Java.IO.InputStream.Read(Byte[] b, Int32 off, Int32 len) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Java.IO.InputStream.cs:line 247
   at Android.Runtime.InputStreamInvoker.Read(Byte[] buffer, Int32 offset, Int32 count) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/InputStreamInvoker.cs:line 87
   at System.IO.Stream.<>c.<BeginReadInternal>b__38_0(Object <p0>)
   at System.Threading.Tasks.Task`1[[System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__281_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at System.IO.BufferedStream.ReadFromUnderlyingStreamAsync(Memory`1 buffer, CancellationToken cancellationToken, Int32 bytesAlreadySatisfied, Task semaphoreLockTask)
   at System.Text.Json.Serialization.ReadBufferState.ReadFromStreamAsync(Stream utf8Json, CancellationToken cancellationToken, Boolean fillBuffer)
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.<DeserializeAsync>d__1[[System.Collections.Generic.IEnumerable`1[[Doc.Model.Admissions.DentitionModel, Doc.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
   at System.Net.Http.Json.HttpContentJsonExtensions.<ReadFromJsonAsyncCore>d__12`1[[System.Collections.Generic.IEnumerable`1[[Doc.Model.Admissions.DentitionModel, Doc.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
   at Refit.SystemTextJsonContentSerializer.<FromHttpContentAsync>d__4`1[[System.Collections.Generic.IEnumerable`1[[Doc.Model.Admissions.DentitionModel, Doc.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext() in c:\temp\releaser\refit\Refit\SystemTextJsonContentSerializer.cs:line 48
   at Refit.RequestBuilderImplementation.<DeserializeContentAsync>d__16`1[[System.Collections.Generic.IEnumerable`1[[Doc.Model.Admissions.DentitionModel, Doc.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext() in c:\temp\releaser\refit\Refit\RequestBuilderImplementation.cs:line 450
   at Refit.RequestBuilderImplementation.<>c__DisplayClass15_0`2.<<BuildCancellableTaskFuncForMethod>b__0>d[[System.Collections.Generic.IEnumerable`1[[Doc.Model.Admissions.DentitionModel, Doc.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Collections.Generic.IEnumerable`1[[Doc.Model.Admissions.DentitionModel, Doc.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext() in c:\temp\releaser\refit\Refit\RequestBuilderImplementation.cs:line 385
   --- End of inner exception stack trace ---
   at Refit.RequestBuilderImplementation.<>c__DisplayClass15_0`2.<<BuildCancellableTaskFuncForMethod>b__0>d[[System.Collections.Generic.IEnumerable`1[[Doc.Model.Admissions.DentitionModel, Doc.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Collections.Generic.IEnumerable`1[[Doc.Model.Admissions.DentitionModel, Doc.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext() in c:\temp\releaser\refit\Refit\RequestBuilderImplementation.cs:line 390

What's currious is that I'm also using the following package to automatically retry in case of failure but I'm still getting the error randomly in 50% of the times that I do try to make http calls. <PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="8.10.0" />

Here is how I'm configuring my http client:

public static class ApiConfigurations
{
    private static readonly string BaseUrl = "https://192.168.15.2:5001";

    public static MauiAppBuilder ConfigureApi(this MauiAppBuilder builder)
    {
        builder.Services
            .AddTransient<AuthenticationHandler>()
            .AddRefitClient<IApi>()
            .ConfigurePrimaryHttpMessageHandler((services) =>
            {
                var provider = services.GetRequiredService<IHttpMessageHandlerProvider>();
                var handler = provider.GetHttpMessageHandler();
                return handler;
            })
            .ConfigureHttpClient(httpClient =>
            {
                httpClient.BaseAddress = new Uri(BaseUrl);
            })
            .AddHttpMessageHandler<AuthenticationHandler>()
            .AddResilienceHandler("defaultResilience", x =>
            {
                x.AddRetry(new RetryStrategyOptions<HttpResponseMessage>
                    {
                        ShouldHandle = new PredicateBuilder<HttpResponseMessage>().Handle<Exception>(),
                        Delay = TimeSpan.FromSeconds(20),
                        MaxRetryAttempts = 3,
                        BackoffType = DelayBackoffType.Exponential,
                        UseJitter = true
                    })
                    .AddTimeout(TimeSpan.FromSeconds(60));
            });
        return builder;
    }
}
public class AuthenticationHandler(IAccessTokenProvider accessTokenProvider, IUserContext userContext) : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (accessTokenProvider.Token == null)
        {
            return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
        }

        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessTokenProvider.Token);

        if (userContext.CurrentCompany?.Id != null)
        {
            request.Headers.Add("currentCompanyId", userContext.CurrentCompany.Id.ToString());
        }

        return await base.SendAsync(request, cancellationToken);
    }
}
public class HttpMessageHandlerProvider : IHttpMessageHandlerProvider
{
    public HttpMessageHandler GetHttpMessageHandler()
    {
        return new AndroidMessageHandler
        {
            ServerCertificateCustomValidationCallback = (request, certificate, chain, sslPolicyErrors) 
                => certificate?.Issuer == "CN=localhost" || sslPolicyErrors == SslPolicyErrors.None
        };
    }
}

Also this this my VS 2022 info

Microsoft Visual Studio Enterprise 2022
Version 17.11.5
VisualStudio.17.Release/17.11.5+35327.3
Microsoft .NET Framework
Version 4.8.09032

Installed Version: Enterprise

ASP.NET and Web Tools   17.11.231.19466
ASP.NET and Web Tools

Azure App Service Tools v3.0.0   17.11.231.19466
Azure App Service Tools v3.0.0

Azure Functions and Web Jobs Tools   17.11.231.19466
Azure Functions and Web Jobs Tools

C# Tools   4.11.0-3.24460.3+5649376e0e5f5db3743a94a62b073f2cce4be5d9
C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

CleanBinAndObjCommand Extension   1.2.58
CleanBinAndObjCommand Visual Studio Extension Detailed Info

Common Azure Tools   1.10
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

Extensibility Message Bus   1.4.39 (main@e8108eb)
Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.

File Explorer   1.0.61
Gives access to all files and folders from the file system under the repo- or solution root folder. All in the same Solution Explorer view.

GitHub Copilot   0.2.1657.32929
GitHub Copilot is an AI pair programmer that helps you write code faster and with less work.

Microsoft Azure Tools for Visual Studio   2.9
Support for Azure Cloud Services projects

Microsoft JVM Debugger   1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

Mono Debugging for Visual Studio   17.11.3 (ba13144)
Support for debugging Mono processes with Visual Studio.

NuGet Package Manager   6.11.1
NuGet Package Manager in Visual Studio. For more information about NuGet, visit https://docs.nuget.org/

Razor (ASP.NET Core)   17.11.3.2442001+68650a7d94261bc56a1f4bc522c2ee35314b1abb
Provides languages services for ASP.NET Core Razor.

SQL Server Data Tools   17.11.47.0
Microsoft SQL Server Data Tools

TypeScript Tools   17.0.30715.2002
TypeScript Tools for Microsoft Visual Studio

Visual Basic Tools   4.11.0-3.24460.3+5649376e0e5f5db3743a94a62b073f2cce4be5d9
Visual Basic components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Visual F# Tools   17.11.0-beta.24421.7+af2f522de602281d4ef5a7b71507c428e814c5c1
Microsoft Visual F# Tools

Visual Studio IntelliCode   2.2
AI-assisted development for Visual Studio.

VisualStudio.DeviceLog   1.0
Information about my package

VisualStudio.Mac   1.0
Mac Extension for Visual Studio

VSColorOutput64   2023.4
Color output for build and debug windows - https://mike-ward.net/vscoloroutput

VSPackage Extension   1.0
VSPackage Visual Studio Extension Detailed Info

Xamarin   17.11.0.98 (d17-11@86652fe)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin Designer   17.11.3.11 (remotes/origin/d17-11@cdbb0a4fdd)
Visual Studio extension to enable Xamarin Designer tools in Visual Studio.

Xamarin.Android SDK   13.2.2.0 (d17-5/45b0e14)
Xamarin.Android Reference Assemblies and MSBuild support.
    Mono: d9a6e87
    Java.Interop: xamarin/java.interop/d17-5@149d70fe
    SQLite: xamarin/sqlite/3.40.1@68c69d8
    Xamarin.Android Tools: xamarin/xamarin-android-tools/d17-5@ca1552d

XAML Styler   3.1
XAML Styler is a visual studio extension that formats XAML source code based on a set of styling rules. This tool can help you/your team maintain a better XAML coding style as well as a much better XAML readability.
jonathanpeppers commented 1 week ago

@ederbond can you make a small sample that shows the problem? The reason we don't have a fix, is we don't have a good repro...

What we tried so far was this, but it already shipped:

ederbond commented 1 week ago

@jonathanpeppers I could give you access to my AzureDevOps project could you tell me what's your e-mail Address?

jonathanpeppers commented 1 week ago

My gmail address is on GitHub profile.

ederbond commented 1 week ago

@jonathanpeppers I've just granted you access to my project source code on Azure Dev Ops and sent you the details to your e-mail. Please let-me know if you have received it and need any help to run it on your machine.

jonathanpeppers commented 1 week ago

@ederbond if we have to pass this off to the .NET runtime team, is there a way this can be turned into a smaller sample that we can freely share?

ederbond commented 6 days ago

@jonathanpeppers right now I'm kind of fully packed of work on my current Job so I can stop to create an end-to-end repro sample. If you need to share it with other folks from the .NET runtime team, fell free to copy my project's source code to an internal private git repo of yours and just ask others to do not expose it publicly.

BTW where you able to reproduce the issue on your end?

zuo99 commented 5 days ago

I encountered the same issue, where this error occasionally occurs when downloading data

zuo99 commented 5 days ago

I tested it, and using this is OK.*.csproj add PropertyGroup> UseNativeHttpHandler>false</UseNativeHttpHandler PropertyGroup>