Jonathan Wood
Jonathan Wood

Reputation: 67195

How to dispose HttpClient after it's finished?

I want to use HttpClient to get content for my web page.

public async Task<IActionResult> OnGet()
{
    NetworkCredential credentials = new NetworkCredential(Settings.Username, Settings.Password);

    using (HttpClientHandler handler = new HttpClientHandler { Credentials = credentials })
    using (HttpClient httpClient = new HttpClient(handler))
    {
        Content = await httpClient.GetStringAsync(requestUriString);
    }

    return Page();
}

The problem is that my using statements cause the HttpClient and HttpClientHandler objects to be destroyed before GetStringAsync() has completed.

I can remove the using statements, but then I can't be assured the connections get disposed in a timely fashion.

Note that HttpClient does not implement IAsyncDisposable and so using await using is not an option.

How can I ensure my HTTP objects get disposed of as soon as possible without disposing them before the code is finished?

Upvotes: 3

Views: 8198

Answers (2)

sunero4
sunero4

Reputation: 840

So HttpClient is actually a bit weird in the context of being an IDisposable. Even though it implements the IDisposable interface, Microsoft actually advises against placing it in a using statement.

If you are using it in an ASP.NET Core context, you should use the HttpClientFactory to manage the lifetime of your HttpClients. If not, it is recommended to use a single static instance, but be wary that this can cause other issues, such as DNS staleness.

Upvotes: 7

bougiemane
bougiemane

Reputation: 33

I found this article helpful when I had a similar issue: https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/ Here's an excerpt of the code you're looking for:

private static HttpClient Client = new HttpClient();
public static async Task Main(string[] args) 
{
    Console.WriteLine("Starting connections");
    for(int i = 0; i<10; i++)
    {
        var result = await Client.GetAsync("http://aspnetmonsters.com");
        Console.WriteLine(result.StatusCode);
    }
    Console.WriteLine("Connections done");
    Console.ReadLine();
}

Upvotes: 0

Related Questions