HttpClient - Lifetime Intent?

This may be a complete noob question, however, what is the intended lifetime of an HttpClient instance?

In other words, should a new instance of the HttpClient be created on a per call/request basis or 'could' it be used for a longer period with multiple calls to Get/Put etc. such as for the duration of some session (where session is a medium term period,
perhaps not an entire application lifetime) for a particular View/ViewModel lifetime in WPF application.

I'm not seeing much guidance on its specific use pattern and many of the examples are too simple to require a more complex use of the class.

I would not recommend using HttpClient across threads, but I don't see an issue with using it again after a cancelled request. Out of curiosity, why are you trying to use the client across threads? Is it to avoid re-configuring the default headers
and the HttpClientHandler/WebRequestHandler?

Perhaps its my lack of understanding regarding the client, but yes, I am struggling with where exactly to put this configuration handling/setup.

My use case is like this:

I have a ViewModel that has the concept of an Authenticated Session (ISessionClient - a REST client to Java backend).
The ViewModel may make several asynchronous calls for various resources simultaneously.
The implementation of ISessionClient uses HttpClient to make REST requests.
The methods of the ISessionClient (such as IAsyncRequest Fetch<T>(Uri resourceUri, Action<T> resultHandler, ...) ) use a Task<T> internally to make a request against an HttpClient instance that has credentials, proxy, etc. set on an HttpClientHandler
passed to the HttpClient when it is constructed.
Any or all request may be cancelled at any time via user interaction (cancel button).

I was finding that initial requests were slow when I had to go through that config each time (particularly for proxy auto discovery). So I was hoping to leverage a one-time config that I could use for the duration of the ViewModels lifetime (usually
a short lived task with associated view).

A good example for this real world use case scenario would be awesome!

The HttpClient should have it's lifetime scoped to at least the viewmodel in my opinion. The problem with disposing the HttpClient is that it disposes the HttpClientHandler that then closes the HTTP Connection. It is re-opening that Http connection
that is expensive.

I'm not a huge fan of the fact that we can pass in a HttpClientHandler into the HttpClient but then disposing the HttpClient disposes the handler. Seems counter-intuitive to me. Hopefully the team will clarify their think around this design at some
point. I hear that some people are working on more documentation :-)

My thought exactly and you confirmed my experience and hence my questioning. I saw that the handler was disposed when the client was disposed...

It would be great to have handlers that could live between client instances.
In the case of HttpClientHandler (and derived types) keeping the handler alive would be hugely beneficial in many ways: think cookies, credentials, proxy, certification, and other custom configurations, etc.

Perhaps for my use case I can use an instance of HttpClient (and associated HttpClientHandler) until a request is cancelled then recreate the client again. Not really what I'd like to do!

Any suggestions on what other folk are doing for this case would be great!

By design handlers cannot be used across clients. The reasoning is that the innermost handler touches the wire i.e. it manages the actual network connection. The advantage as Darrel said is one the connection resources are created you don't pay a continual
cost every time you send a connection. Remember also we use handlers on the server, on the server the outermost handler is hooked to the service endpoint and the innermost handler touches the wire.

Darrel, while the initial configuration of the HttpClient should be done up front in a thread safe way, it should be completely safe to call SendAsync from multiple thread at the same time. If you find otherwise please let us know.

Yes, HttpClient should also be safe to re-use after a cancelled request.

If the default Dispose pattern does not suit your needs, remember that these components are extensible so you can override Dispose on HttpClient or HttpClientHandler, or insert an intermediate handler between them to modify the behavior.

Thanks for confirming that. It does make sense that SendAsync would be thread safe!

That does remind me though that there was an issue in earlier versions with HttpContent Headers not being thread-safe. I just re-tested this with preview 5 and I can repro the issue with the following code:

Why don't I use SendAsync?
Because I need to do a few things before and after the call to Send and therefore it needs to be synchronous within the Task. One thing in particular is that I need to handle an HttpStatusCode.Unauthorized responses (amongst others) which in this case
will call out to a CredentialsProvider (which may be handled by a UI Logon service). I want to do this in that task so that it is handled in one place and also so that it will be triggered when the service times out the authorization due to a idle time (coffee
break!). So from the ViewModel I wand to call my ISessionClient.Fetch<T>(Uri resourceUri, Action<T> resultHandler, ...) and merrily let the underlying Task logic handle the re-authentications etc on a background thread.

Putting threading aside for one moment... here are some of the problems I'm encountering:

1) It appears that on the first call to to Send/SendAsync on HttpClient (with HttpClientHandler handler) the instance is locked down to prevent property changes to Credentials etc. This is a problem because it forces me to dispose the current client
and handler and all my config and recreated the HttpClient with new Credentials and try again - an expensive process.

2) Unconfirmed, BUT, the HttpClient creates an internal CancellationTokenSource (pendingRequestsCts) that is linked to my cancellation Token I pass in the call to Send on the HttpClient. If my understanding is correct, once any linked Token is cancelled
all linked Tokens are cancelled (a desired effect) AND the pendingRequestsCts flags that it is cancelled (also a desired effect). However, it appears there is no way to 'uncancel' or reset this and once again it forces me to recreate the client.
Have I misunderstood how the CancellationTokenSource with linked CancellationTokens works? Does the CancellationTokenSource reset itself somehow or does the HttpClient create a new one on the next call to send or is the client rendered permanently 'cancelled'!?

[On further investigation I see in HttpClient.CancelPendingRequests a call to Interlocked.Exchange(ref pendingRequestsCts, new CancellationTokenSource()) - is this how I should 'reset' the cancelled state. If so it would be great to have the locked
down properties 'released' for modification at this point too! Would this not provide a way for better re-use.]

Something smells about an attempt to re-use the HttpClient - I'm very open to suggestions on how I can maximise reuse of an already configured (and authenticated) HttpClient so as to minimise expensive reconfig scenarios (such as when there is an auth timeout).

Thank you for all the input on this subject.
(A little background on this is that our project is creating a WPF/Metro front end for a system used for medical purposes for a client base of approximately 3000 users - UI response times are critical and therefore UI interactions require efficient and mainly
concurrent async loading of resources/data/tasks/etc)

Interesting repro. Note that while HttpClient and handlers are designed for reuse and thread safety, messages and content are designed for single use and have the default .NET no-thread-safety-guarantee. This is a practical tradeoff to maintain acceptable
performance in the API. If there are specific items that need thread safety, or that appear to be very thread fragile, let us know. The example above looks like it withstood quite a bit of abuse.

1) Have you tried assigning a CredentialCache and then adding new credentials as you go?

2) That's not quite accurate. HttpClient takes pendingRequestsCts and your CTS and creates a third request CTS that has the timeout assigned to it and is then passed on with the request. Canceling your CTS will cancel the request
CTS, but not the pendingRequestsCts. Similarly the timeout will only affect the request CTS, not pendingRequestsCts or your CTS.

Today I have an implementation for reuse of the HttpClient in a multi-threaded use case and for now it seems to be holding up well. I still need to fully test it.

I have one other scenario that the CredentialCache may be able to solve for me. During the lifetime of an 'Authenticated Session' (a concept) the first time a request goes across the wire I will get a 401 which causes the Auth Session code to capture
credentials and then reattempt the request (also another reason for my own task and not using the SendAsync).

Once the request is authenticated the server provides session id in the form of a cookie which is used to identify and authenticate a task session. Once this id is available there is no further need to supply credentials for any calls on that client.
I guess here I could remove the associated credentials from the cache and continue with the session id.

I realize that the repro test I sent was a little extreme but we did first run into the issue in a realistic scenario. In my RESTAgent (http://restagent.codeplex.com) project, when I receive a response I do two things. One, I dispatch control
to a response handler based on the content type and two I read and parse the payload looking for links. This processing of the payload is done on a background thread because often the user-agent needs time to prep some kind of UI before it can display
the data contained in the representation. Sporadically our formatters would choke when they attempted to process the HTTP Content.

I suspect as HttpClient moves to an all async model, it may become more frequent for other people to do this kind of thing.