如何在构造函数中正确实例化静态HttpClient

时间:2018-10-11 13:23:02

标签: c# locking httpclient

我有一个自定义的HttpClient实现,需要从配置中获取一些值才能正常工作。

public class MyHttpClient : HttpClient
{
    public MyHttpClient()
    {
    }

    public MyHttpClient(string token)
    {
        Token = token;
    }

    public string Token { get; set; }

    // ...
}

我现在想在我的使用IOptions<TOptions>进行配置的应用程序逻辑中使用此HttpClient。

public class MyLogic
{
    private static MyHttpClient Client;

    public MyLogic(IOptions<MyConfig> config)
    {
        // How to instantiate Client with values from config?
    }
}

自从HttpClient should be held as a static field开始,我就无法将config值注入到HttpClient中。我想出了几种可能性,但似乎都没有。

选项1 每次设置配置值

public class MyLogic
{
    private static MyHttpClient Client = new MyHttpClient();

    public MyLogic(IOptions<MyConfig> config)
    {
        Client.Token = config.Value.Token;
    }
}

这似乎是最糟糕的选择,因为Token的值可能会随着HttpClient使用它而改变。

选项2 每次锁定

public class MyLogic
{
    private static MyHttpClient Client;
    private static readonly object ClientLock = new object();

    public MyLogic(IOptions<MyConfig> config)
    {
        lock(ClientLock)
        {
            if (Client == null)
            {
                Client = new MyHttpClient(config.Value.Token);
            }
        }
    }
}

从性能的角度看,这似乎是不好的,因为MyLogic的每个实例都将创建一个锁并阻塞所有其他锁。

选项3 双重检查锁定

public class MyLogic
{
    private static volatile MyHttpClient Client;
    private static readonly object ClientLock = new object();

    public MyLogic(IOptions<MyConfig> config)
    {
        if (Client == null)
        {
            lock(ClientLock)
            {
                if (Client == null)
                {
                    Client = new MyHttpClient(config.Value.Token);
                }
            }
        }
    }
}

这似乎是解决方案,但是很难正确检查双重检查的锁,因此应该避免。

可悲的是,Lazy<T>似乎不是一个选择,因为它还需要静态上下文来创建实例。

那么,在这种情况下实例化HttpClient的最佳选择是什么?

1 个答案:

答案 0 :(得分:0)

@Damien_The_Unbeliever:

由于我无法添加评论,因此我必须进行“完整答复”: 问题的方向是,当应用程序在Android设备上运行时,如何确保共享项目(既不是Android也不是iOS专用)中的HttpClient实例正确选择Android HttpClient实现。< / p>