-
Notifications
You must be signed in to change notification settings - Fork 5k
HttpClient async calls not throwing TaskCanceledException on Android when token canceled #99568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
That's confusing to me, as WebException is part of System.Net.Requests, which HttpClient in .NET Core doesn't use at all; WebRequest is built on top of HttpClient, not the other way around. Can you share the full stack trace from the exception you're receiving? Is it possible you're actually running on the old mono (https://github.com/mono/mono) rather than on .NET 8? |
Ah, this might be coming from the Mono.Android HttpClientHandler that gets substituted in on Android (and which is not part of this repo). @steveisok ? |
@simonrozsival, is that expected behavior from the Android handler? |
Updated my posting for that. Sorry, should have included that to begin with. |
@mdemler if you put |
Thanks, @steveisok! I've done that, and that will work for us for what we're trying to handle now. It would be nice if this worked as expected even when using the native handler though. Thanks again. |
It's a known issue: dotnet/android#5761 @grendello do you know why we haven't changed the exceptions to |
@simonrozsival IIRC it was backward compatibility with classic. Shouldn't be an issue anymore |
The right time to change this behaviour was when going from Xamarin to Core. It's shameful that this wasn't done then. My other issue, linked above, was opened more than three years ago and nobody seems to care that impossible exceptions are being thrown from within the framework. false might be a resolution or it might not. It's disingenuous to suggest that without also documenting exactly the benefits and drawbacks of moving away from Android's native HTTP stack. |
private async void OnInternetConnectionSuccess()
{
try
{
using var httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromSeconds(5);
var reply = await httpClient.GetAsync($"{AppSettings.ApiSettings.ConnectionUrl}/health");
if (!reply.IsSuccessStatusCode)
{
OnFailedToConnectWithServer?.Invoke();
return;
}
var result = await _apiService.GetClientAppConfig();
string appVersion = AppInfo.Current.VersionString;
string configAppVersion =
result.VersionSettings.ImportantUpdateVersion.ToString(CultureInfo.InvariantCulture);
if (!appVersion.Equals(configAppVersion))
{
OnImportantUpdateAvailable?.Invoke();
return;
}
OnUpdateNotAvailable?.Invoke();
}
catch (HttpException e)
{
_logger.LogError("AuthenticationViewModel Error : {message}", e.Message);
}
catch (TaskCanceledException e)
{
_logger.LogError("AuthenticationViewModel Error : {message}", e.Message);
}
catch (Exception e)
{
_logger.LogError("AuthenticationViewModel Error : {message}", e.Message);
OnFailedToConnectWithServer?.Invoke();
}
}
private void OnInternetConnectionFailed()
{
OnFailedToConnectWithInternet?.Invoke();
} var reply = await httpClient.GetAsync($"{AppSettings.ApiSettings.ConnectionUrl}/health"); when i debug the task was cancelling in this line without throwing any errors why ? have any idea. |
2025-04-07.17-57-14.mp4i have this same issue in both windows and android, console application and maui application. and maui application was not crashing or close noting happening when this issue happen, it running normally. |
just now i saw the task was waiting until 1:45Min and after throwing exception. i try using httpClient timeout, SocketsHttpHandler timeout, cancellationTokenSource timeout and Ping() class all are behave same anyone know why ? |
Description
When running on Windows, TaskCanceledException is being thrown by async HttpClient calls when the timeout elapses. When running the same code under Android, receiving a WebException instead.
Reproduction Steps
`
using var client = new HttpClient();
`
Expected behavior
Behavior is identical between Windows and Android. TaskCanceledException is thrown for both.
Actual behavior
WebException is thrown when a timeout is reached.
{System.Net.WebException: Socket closed ---> Java.Net.SocketException: Socket closed at Java.Interop.JniEnvironment.InstanceMethods.CallIntMethod(JniObjectReference instance, JniMethodInfo method, JniArgumentValue* args) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/obj/Release/net7.0/JniEnvironment.g.cs:line 20203 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 511 at Java.Net.HttpURLConnection.get_ResponseCode() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Java.Net.HttpURLConnection.cs:line 521 at Xamarin.Android.Net.AndroidMessageHandler.<>c__DisplayClass136_0.<DoProcessRequest>b__2() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 625 at System.Threading.Tasks.Task
1[[System.Net.HttpStatusCode, System.Net.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].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 Xamarin.Android.Net.AndroidMessageHandler.DoProcessRequest(HttpRequestMessage request, URL javaUrl, HttpURLConnection httpConnection, CancellationToken cancellationToken, RequestRedirectionState redirectState) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 625
at Xamarin.Android.Net.AndroidMessageHandler.DoSendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 456
--- End of managed Java.Net.SocketException stack trace ---
java.net.SocketException: Socket closed
at java.net.SocketInputStream.read(SocketInputStream.java:188)
at java.net.SocketInputStream.read(SocketInputStream.java:143)
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readFromSocket(ConscryptEngineSocket.java:945)
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:909)
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readUntilDataAvailable(ConscryptEngineSocket.java:824)
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.read(ConscryptEngineSocket.java:797)
at com.android.okhttp.okio.Okio$2.read(Okio.java:138)
at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:213)
at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:307)
at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:301)
at com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:197)
at com.android.okhttp.internal.http.Http1xStream.readResponse(Http1xStream.java:188)
at com.android.okhttp.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:129)
at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:750)
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:622)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:475)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:106)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:30)
--- End of managed Java.Net.SocketException stack trace ---
java.net.SocketException: Socket closed
at java.net.SocketInputStream.read(SocketInputStream.java:188)
at java.net.SocketInputStream.read(SocketInputStream.java:143)
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readFromSocket(ConscryptEngineSocket.java:945)
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:909)
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readUntilDataAvailable(ConscryptEngineSocket.java:824)
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.read(ConscryptEngineSocket.java:797)
at com.android.okhttp.okio.Okio$2.read(Okio.java:138)
at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:213)
at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:307)
at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:301)
at com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:197)
at com.android.okhttp.internal.http.Http1xStream.readResponse(Http1xStream.java:188)
at com.android.okhttp.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:129)
at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:750)
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:622)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:475)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:106)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:30)
--- End of inner exception stack trace ---
at Xamarin.Android.Net.AndroidMessageHandler.DoSendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 471
at System.Net.Http.HttpClient.g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at MauiApp4.MainPage.RunTestAsync() in C:\Projects\Temp\MauiApp4\MauiApp4\MainPage.xaml.cs:line 41}
`
Regression?
Not sure. This is new code.
Known Workarounds
Unknown. Defeats the ability to use Polly to retry on a timeout.
Configuration
.NET 8.0.200
Windows 11.
Device: SAMSUNG A9+, Android 13. Same behavior on Emulator running Android 13.
Other information
No response
The text was updated successfully, but these errors were encountered: