Closed
Description
Describe the bug
my legacy app is still running on ASP.NET,
after internal library implementation adopting the HttpClientFactory managed HttpClient,
async call with await in HttpClient never returns.
this issue is very similar to #563
To Reproduce
dotnet new console -o Console1
cd Console1
dotnet add package Microsoft.Extensions.DependencyInjection --version 2.2.0
dotnet add package Microsoft.Extensions.Http --version 2.2.0
Program.cs
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
namespace Console1
{
public class Program
{
static void Main(string[] args)
{
var services = new ServiceCollection();
services.AddHttpClient();
var provider = services.BuildServiceProvider();
var factory = provider.GetRequiredService<IHttpClientFactory>();
var client1 = new HttpClient();
SingleThreadedSynchronizationContext.Run(() =>
{
Console.Write("default HttpClient in single-threaded SynchronizationContext ... ");
client1.GetAsync("http://example.com").GetAwaiter().GetResult();
Console.WriteLine($"Done");
});
var client2 = factory.CreateClient();
SingleThreadedSynchronizationContext.Run(() =>
{
Console.Write("managed HttpClient in single-threaded SynchronizationContext ... ");
client2.GetAsync("http://example.com").GetAwaiter().GetResult();
Console.WriteLine($"Done");
});
}
}
public class SingleThreadedSynchronizationContext : SynchronizationContext
{
private readonly Queue<(SendOrPostCallback Callback, object State)> _queue = new Queue<(SendOrPostCallback Callback, object State)>();
public override void Post(SendOrPostCallback d, object state)
{
_queue.Enqueue((d, state));
}
public static void Run(Action action)
{
var previous = Current;
var context = new SingleThreadedSynchronizationContext();
SetSynchronizationContext(context);
try
{
action();
while (context._queue.TryDequeue(out var item))
{
item.Callback(item.State);
}
}
finally
{
SetSynchronizationContext(previous);
}
}
}
}
Run this code
$ dotnet run
default HttpClient in single-threaded SynchronizationContext ... Done
managed HttpClient in single-threaded SynchronizationContext ...
you will see the second async call with await in HttpClient hangs
Expected behavior
HttpClientFactory managed HttpClient should also working in single-threaded SynchronizationContext
Screenshots
Additional context
$ dotnet --info
.NET Core SDK (reflecting any global.json):
Version: 2.2.103
Commit: 8edbc2570a
Runtime Environment:
OS Name: Mac OS X
OS Version: 10.14
OS Platform: Darwin
RID: osx.10.14-x64
Base Path: /usr/local/share/dotnet/sdk/2.2.103/
Host (useful for support):
Version: 2.2.1
Commit: 878dd11e62
.NET Core SDKs installed:
2.2.103 [/usr/local/share/dotnet/sdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.2.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.2.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.2.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
To install additional .NET Core runtimes or SDKs:
https://aka.ms/dotnet-download
Metadata
Metadata
Assignees
Labels
No labels