0

Is it possible to create one instance of httpclient in Xamarin Forms application in OnStart() and use it everywhere in my application?

observer
  • 2,925
  • 1
  • 19
  • 38
Afshin
  • 149
  • 1
  • 2
  • 9
  • 1
    Is not a good idea, HttpClient should be called in thead safe and should be disposable to close correctly all network connections – OrcusZ Aug 16 '17 at 14:21
  • @OrcusZ that's not true at all. You should absolutely reuse a single instance of HttpClient. [Similar question](https://stackoverflow.com/questions/15705092/do-httpclient-and-httpclienthandler-have-to-be-disposed) – Will Decker Aug 16 '17 at 17:52
  • @WillDecker So MS Doc & Sources are wrong ? You can use a single instance or createInstance method. But you should check if the instance need to be dispose. Furthermore the HttpClient is already thread safe but not all the methods, so you should use the methods in a thread safe scenario – OrcusZ Aug 17 '17 at 05:18
  • @OrcusZ you should reuse the HttpClient. It creates expensive resources on create. It's thread safe, so there is not a reason to use an expensive resource continuously. – Nick Turner Aug 29 '19 at 16:36
  • @NickTurner wow all thread ^^. Yes it's true, I read a lot about async call & http call in xForms, and it's better to keep only one connection for performance purpose :) – OrcusZ Sep 01 '19 at 18:31

1 Answers1

3

Yes you can use the same httpclient for all request in your app. But you will need to take note that if there is API that is having different base URL or headers information, then you will need to create another httpclient for that.

What I do is I have a class to manage the HttpClient instances. If there is no instance that is matching the HttpConfig, it will create and store it. If there is already an existing instance, it will just return it.

Example of code (HttpService is dependency injected):

public class HttpService : IHttpService
{
    private static readonly int MAX_CLIENT = 5;

    private Dictionary<HttpConfig, HttpClient> mClients;
    private Queue<HttpConfig> mClientSequence;

    public HttpService()
    {
        mClients = new Dictionary<HttpConfig, HttpClient>();
        mClientSequence = new Queue<HttpConfig>();
    }

    private HttpClient CreateHttpClientAsync(HttpConfig config)
    {
        HttpClient httpClient;

        if (mClients.ContainsKey(config))
        {
            httpClient = mClients[config];
        }
        else
        {
            // TODO: Create HttpClient...

            if (mClientSequence.Count >= MAX_CLIENT)
            {
                // Remove the first item
                var removingConfig = mClientSequence.Dequeue();
                mClients.Remove(removingConfig);
            }

            mClients[config] = httpClient;
            mClientSequence.Enqueue(config);
        }

        return httpClient;
    }
...
}

HttpConfig is class where I store BaseUrl, Timeout, Headers, Auth info, etc. You will need to override the Equals method in the class for comparison whether there is existing same config.

public override bool Equals(object obj)
{
    // Logic to determine whether it is same config
}
lowleetak
  • 1,362
  • 1
  • 10
  • 19