runtime: [NativeAOT] Httpclient timeout

Description

httpclient timeout doesn’t work well. I specify timeout equals 2 minutes but actually, it’s 10 seconds.

Error: System.Threading.Tasks.TaskCanceledException: The request was canceled due to the configured HttpClient.Timeout of 120 seconds elapsing.
 ---> System.TimeoutException: The operation was canceled.
 ---> System.Threading.Tasks.TaskCanceledException: The operation was canceled.
 ---> System.TimeoutException: A connection could not be established within the configured ConnectTimeout.
   --- End of inner exception stack trace ---
   at System.Exception.SetCurrentStackTrace() + 0x5c
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.SetCurrentStackTrace(Exception) + 0x15
   at System.Net.Http.HttpConnectionPool.CreateConnectTimeoutException(OperationCanceledException) + 0xb4
   at System.Net.Http.HttpConnectionPool.<AddHttp11ConnectionAsync>d__73.MoveNext() + 0x3bc
   at System.Runtime.EH.DispatchEx(StackFrameIterator&, EH.ExInfo&, UInt32) + 0x1ee
   at System.Runtime.EH.RhThrowEx(Object, EH.ExInfo&) + 0x51
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext, ContextCallback, Object) + 0x7f
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread) + 0x6d
   at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(IAsyncStateMachineBox, Boolean) + 0x9d
   at System.Threading.Tasks.Task.RunContinuations(Object) + 0xc0
   at System.Threading.Tasks.Task.TrySetCanceled(CancellationToken, Object) + 0x64
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetException(Exception, Task`1&) + 0x74
   at System.Net.Http.HttpConnectionPool.<CreateHttp11ConnectionAsync>d__98.MoveNext() + 0x455
   at System.Runtime.EH.DispatchEx(StackFrameIterator&, EH.ExInfo&, UInt32) + 0x1ee
   at System.Runtime.EH.RhThrowEx(Object, EH.ExInfo&) + 0x51
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext, ContextCallback, Object) + 0x7f
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread) + 0x75
   at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(IAsyncStateMachineBox, Boolean) + 0x9d
   at System.Threading.Tasks.Task.RunContinuations(Object) + 0xc0
   at System.Threading.Tasks.Task.TrySetCanceled(CancellationToken, Object) + 0x64
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetException(Exception, Task`1&) + 0x74
   at System.Net.Http.HttpConnectionPool.<ConnectAsync>d__96.MoveNext() + 0xa8e
   at System.Runtime.EH.DispatchEx(StackFrameIterator&, EH.ExInfo&, UInt32) + 0x1ee
   at System.Runtime.EH.RhThrowEx(Object, EH.ExInfo&) + 0x51
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext, ContextCallback, Object) + 0x7f
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread) + 0x75
   at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(IAsyncStateMachineBox, Boolean) + 0x9d
   at System.Threading.Tasks.Task.RunContinuations(Object) + 0xc0
   at System.Threading.Tasks.Task.TrySetCanceled(CancellationToken, Object) + 0x64
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetException(Exception, Task`1&) + 0x74
   at System.Net.Http.HttpConnectionPool.<ConnectToTcpHostAsync>d__97.MoveNext() + 0x7d0
   at System.Runtime.EH.DispatchEx(StackFrameIterator&, EH.ExInfo&, UInt32) + 0x1ee
   at System.Runtime.EH.RhThrowEx(Object, EH.ExInfo&) + 0x51
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext, ContextCallback, Object) + 0x7f
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread) + 0x75
   at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(IAsyncStateMachineBox, Boolean) + 0x9d
   at System.Threading.Tasks.Task.RunContinuations(Object) + 0xc0
   at System.Threading.Tasks.Task.TrySetCanceled(CancellationToken, Object) + 0x64
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetException(Exception, Task`1&) + 0x6f
   at System.Net.Sockets.Socket.<<ConnectAsync>g__WaitForConnectWithCancellation|281_0>d.MoveNext() + 0x38c
   at System.Runtime.EH.DispatchEx(StackFrameIterator&, EH.ExInfo&, UInt32) + 0x1ee
   at System.Runtime.EH.RhThrowEx(Object, EH.ExInfo&) + 0x51
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext, ContextCallback, Object) + 0x7f
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread) + 0x6d
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.InvokeContinuation(Action`1, Object, Boolean, Boolean) + 0x14d
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs) + 0x86
   at System.Net.Sockets.SocketAsyncEventArgs.<<DnsConnectAsync>g__Core|112_0>d.MoveNext() + 0xa1d
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext, ContextCallback, Object) + 0x7f
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread) + 0x6d
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext, ContextCallback, Object) + 0x7f
   at System.Net.Sockets.SocketAsyncEventArgs.<>c.<.cctor>b__176_0(UInt32, UInt32, NativeOverlapped*) + 0x111
   at System.Threading.ThreadPoolBoundHandle.OnNativeIOCompleted(IntPtr, IntPtr, IntPtr, UInt32, UIntPtr, IntPtr) + 0x95
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb6
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task) + 0x42
   at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.<WaitWithCancellationAsync>d__1.MoveNext() + 0x170
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0x4e
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task) + 0x42
   at System.Net.Http.HttpConnectionPool.<GetHttp11ConnectionAsync>d__75.MoveNext() + 0x3ee
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0x4e
   at System.Net.Http.HttpConnectionPool.<SendWithVersionDetectionAndRetryAsync>d__83.MoveNext() + 0x8ec
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0x4e
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task) + 0x42
   at System.Net.Http.RedirectHandler.<SendAsync>d__4.MoveNext() + 0x1ee
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0x4e
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task) + 0x42
   at System.Net.Http.HttpClient.<<SendAsync>g__Core|83_0>d.MoveNext() + 0x164
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpClient.HandleFailure(Exception, Boolean, HttpResponseMessage, CancellationTokenSource, CancellationToken, CancellationTokenSource) + 0x2b7
   at System.Net.Http.HttpClient.<<SendAsync>g__Core|83_0>d.MoveNext() + 0x3ff
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0x4e
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task) + 0x42
   at KeyAuth.api.<req>d__22.MoveNext() + 0x244
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0x4e
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task) + 0x42
   at KeyAuth.api.<init>d__12.MoveNext() + 0x273

Reproduction Steps

 private async static Task<string> req(NameValueCollection post_data)
       {

               IDictionary<string, string> dict = new Dictionary<string, string>();
               foreach (var k in post_data.AllKeys)
               {
                   dict.Add(k, post_data[k]);
               }
               using (var postContent = new FormUrlEncodedContent(dict))
               using (HttpClient client = new HttpClient())
               {
               client.Timeout = TimeSpan.FromMinutes(2);
                   using (HttpResponseMessage response = await client.PostAsync("https://keyauth.win/api/1.0/", postContent))
                   {
                       response.EnsureSuccessStatusCode(); // Throw if httpcode is an error
                       using (HttpContent content = response.Content)
                       {
                           return  await content.ReadAsStringAsync();
                       }
                   }

               }           
           
       }

Expected behavior

wait 120 seconds.

Actual behavior

wait 10 seconds.

Regression?

No response

Known Workarounds

No response

Configuration

.NET 6.0 Windows 11 X64

Other information

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 35 (20 by maintainers)

Most upvoted comments

The change in default ConnectTimeout is getting reverted in https://github.com/dotnet/runtime/pull/68649

yes, but I use .Net 6.

You are not using .NET 6 runtime with 7.0.0-preview.4.22212.4 ILCompiler package. The ILCompiler package comes with a copy of the core framework (including HttpClient), so your AOT build is really using .NET 7 preview4.

We plan to eliminate the need to reference the ILCompiler package for the 7.0 release and replace with a property that you set to enable AOT compilation, so this sort of version mismatch is going to disappear for 7.0 release.

Console.WriteLine(System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(HttpClient).Assembly.Location).ProductVersion);

This would not work with NativeAOT (the IL assemblies do not exist on disk, everything is linked into one binary). It is obvious what it would print: 6.0… without AOT and 7.0… with AOT.

Can you please try to run .NET 7 preview SDK from https://github.com/dotnet/installer, bump your project to net7, run it on .NET 7 runtime without AOT and see whether you see the same problem as with AOT?

@AhmedZero could you please reduce this to a minimal runnable sample that still reproduces the issue?