HttpClient wrapper for simple calls with optional cert
As is this does not work because multiple requests will concurrently operate on the same variables (instance variables and HttpClient internal state as it is being configured).

This is fairly easy to solve because there's a nice pattern for this. Your core problem is that you need to initialize one expensive object for each instance of a certain kind of key (here: HttpClient and certificate path).

I'm modifying some existing code to ensure that only one HttpClient per key is ever created:

public static class HttpClientManager
{
    private static ConcurrentDictionary&lt;string, Lazy&lt;HttpClient&gt;&gt; _clients = 
        new ConcurrentDictionary&lt;string, Lazy&lt;HttpClient&gt;&gt;();

    public static HttpClient Get(string certificatePath)
    {
        return _clients.GetOrAdd(certificatePath, _ =&gt;
            new Lazy&lt;HttpClient&gt;(CreateClient(certificatePath));
    }  

    static HttpClient CreateClient(string certificatePath)
    {
        //TODO
    }
}


You only need to fill in the TODO.

This code is thread safe because the infrastructure takes care of only invoking your factory method once per unique certificatePath. The factory will only use local state so that it is totally unconcerned with thread safety.



I'd avoid methods such as void SetUpXxx(...). These messods make use of side-effects for no reason. In particular, _clientHandler seems to be used only as a way to thread this value through the various methods being called. It is often better to avoid passing data in such covert ways. Convert that field to a method parameter and explicitly pass that value around. I'd do the same thing for _client itself. Then, you can keep the SetUpXxx methods but they become static. It will be explicit what data they consume and what they output.

This might seems like a subtle point but I found this kind of change helpful over and over again.