Skip to content

Http2Connection keeps the ExecutionContext of the first request alive #80232

@MihaZupan

Description

@MihaZupan

As part of setting up the Http2Connection we spin up two background tasks for the read/write channel and in doing so we capture the execution context of the request that initiated the new connection.

We should do the SuppressFlow/RestoreFlow dance somewhere around Http2Connection.SetupAsync. This could also keep it alive.

Repro (note that the finalizer doesn't run until you dispose the client):

var client = new HttpClient
{
    DefaultRequestVersion = HttpVersion.Version20
};

await SendRequest(client);

_ = Task.Run(async () =>
{
    await Task.Delay(5_000);
    Console.WriteLine("Disposing the client");
    client.Dispose();
});

for (int i = 1; ; i++)
{
    Console.WriteLine(i);
    GC.Collect();
    GC.WaitForPendingFinalizers();
    await Task.Delay(1000);
}

async Task SendRequest(HttpClient client)
{
    var asyncLocal = new AsyncLocal<Finalizable>();
    asyncLocal.Value = new Finalizable();
    
    await client.GetStringAsync("https://httpbin.org/ip");
}

public sealed class Finalizable
{
    ~Finalizable() => Console.WriteLine("Finalizer");
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-System.Net.Httpbugin-prThere is an active PR which will close this issue when it is mergedtenet-performancePerformance related issue

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions