MVC4 中使用城堡温莎的 HttpClient 的生活方式

Posted

技术标签:

【中文标题】MVC4 中使用城堡温莎的 HttpClient 的生活方式【英文标题】:Lifestyle of a HttpClient in MVC4 using castle-windsor 【发布时间】:2016-04-24 20:28:21 【问题描述】:

在网络请求中,我想使用 Microsoft HttpClient 调用另一台服务器。我正在使用 MVC4(托管在 IIS 中),并将城堡温莎用作 IOC 容器。我读到 HttpClient 被设计为在多次调用期间存在,我的问题是我应该如何实现它。

我想出了几个选择:

    忽略 HttpClient 是为多次调用而设计的,每次需要时都创建一个新的。 创建一个 Singleton(lifestyle in castle) 对象,该对象在调用之间存储 HttpClient。这有什么风险吗?如果多个 Web 请求使用同一个 HTTP 客户端,性能会变差吗?

有没有更好的模式来做到这一点?

【问题讨论】:

【参考方案1】:

我会使用LifestyleTransient 为每个请求创建一个新请求。当您不确定该类是否可以作为单例运行时,这是最安全的。

依赖抽象(接口)而不是直接依赖 HttpClient 也不是一个坏主意,除非您确定除了发出 HTTP 请求之外永远不会使用该类。即使这样,它也可能使单元测试更容易。这是使用 Windsor 或其他 DI 容器的一大好处。否则,仅在您的班级中直接实例化 HttpClient 并没有太大的好处。


更新。我做了一些查找,发现this answer 表明HttpClient 应该用于给定的API。它受到高度评价,我没有看到任何来自经验(或其他方面)的异议,因此我将在进行一些近期开发时参考它。

我将通过定义一个实现接口的强类型客户端类来实现这一点,然后根据我的类中的接口(而不是直接在客户端上)。然后 Windsor 可以为接口创建类并将其维护为单身人士。

【讨论】:

这是否意味着HttpClient 可以同时处理多个调用(来自不同线程)并具有良好的性能?如果调用是在锁中进行的,那么性能会很差,在这种情况下,实现HttpClient 池可能是个好主意 这就是讨论所表明的。事实上,它表明不这样做可能会导致性能问题。我还没有任何高容量的经验,这就是为什么我建议谨慎行事,但我有一些类似的工作即将完成,所以我将继续寻找确定的东西。但答案、赞成票和 cmets 是一个很好的例子。 非常感谢您的 cmets。我将 HttpClient 实现为单例。我还发现了来自 Microsoft 的 HttpClient 的 documentation(针对 .Net Framwork 4.5 和 4.6 进行了更新),这表明一堆方法实际上是线程安全的。【参考方案2】:

默认情况下,如果您为每个调用创建一个新的 HttpClient 实例,那么每个调用都会创建一个新的 TCP 连接,这会导致延迟并降低吞吐量。如果你想要一个新的 HttpClient 实例,因为它上面有每次调用的数据,那么你可以有一个单例 HttpClientHandler,将它传递给 HttpClient ctor,这将在 HttpClient 实例之间共享 TCP 连接。

Scott,以下是我们使用的三种方法。我希望这会有所帮助,我是***的新手,所以显然不能发布两个以上的链接。

1) 只需要一个静态/单例 HttpClient,并按照 here 的描述使用 HttpRequestMessage 传递任何每次调用的标头

2) 有一个静态/单例 WebRequest|HttpClientHandler,并将其传递给 HttpClient ctor,并将 disposeHandler 设置为 false。

3) 在某些情况下,我们有一个 DelegatingHandler 工具库,需要在每次 HttpClient 调用之后释放。因此,我们创建了一个 WebRequestHandler,它在 Dispose() 中什么都不做,如下所示,将其传递给 DelegatingHandler ctor,然后将 DelegatingHandler 传递给 HttpClient ctor,并将 disposeHandler 设置为 false。

public class LongLivedWebRequestHandler : WebRequestHandler

    public override void Dispose()
    
        // Do nothing...
    

【讨论】:

您能给我推荐任何文档或示例吗?这听起来像是我需要知道的事情。谢谢 是的,文档有点薄。我们发现它从一个 Azure 经典 Web 服务调用另一个,并且我认为我们的出站和入站延迟之间的差异约为 100 毫秒。共享一个长期存在的 WebRequest|HttpClientHandler,每跳惩罚降至约 20 毫秒。有三个有效的例子。

以上是关于MVC4 中使用城堡温莎的 HttpClient 的生活方式的主要内容,如果未能解决你的问题,请参考以下文章

温莎古堡的介绍

C#、温莎城堡和复合设计模式

比较温莎城堡、Unity 和 StructureMap

想在中世纪城堡里当贵族?到欧洲来场建筑巡礼

谁能介绍一下温莎古堡?

温莎古堡是啥时期的建筑呢