Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net core 是否应处置由HttpClientFactory创建的HttpClient实例?_.net Core_Dotnet Httpclient_Idisposable_Asp.net Core 2.1_Httpclientfactory - Fatal编程技术网

.net core 是否应处置由HttpClientFactory创建的HttpClient实例?

.net core 是否应处置由HttpClientFactory创建的HttpClient实例?,.net-core,dotnet-httpclient,idisposable,asp.net-core-2.1,httpclientfactory,.net Core,Dotnet Httpclient,Idisposable,Asp.net Core 2.1,Httpclientfactory,因此,我已在我的Startup.cs中的服务集合中注册了一个命名客户端: services.AddHttpClient(someServiceName, client=>client.BaseAddress=BaseAddress); 现在可以从我的服务提供商处注入IHttpClientFactory 使用此IHttpClientFactory,我创建了一个客户端实例: var client=httpClientFactory.CreateClient(someServiceName) 曾几

因此,我已在我的Startup.cs中的服务集合中注册了一个命名客户端:

services.AddHttpClient(someServiceName,
client=>client.BaseAddress=BaseAddress);
现在可以从我的服务提供商处注入
IHttpClientFactory

使用此
IHttpClientFactory
,我创建了一个客户端实例:

var client=httpClientFactory.CreateClient(someServiceName)
曾几何时,必须非常小心地处理
HttpClient
实例

然而,现在我们有了
HttpClientFactory
,这还重要吗?这个
客户机是否应该/可以放心处置?e、 g

使用(var httpClient=httpClientFactory.CreateClient(someServiceName))
使用(var response=wait-httpClient.PostAsync(somePath,someData))
{
var content=wait response.content.ReadAsAsync();
//...
}

否。您不应处置您的客户。更一般地说,您不应该处理通过DI容器检索到的任何内容,在ASP.NET核心中,DI容器默认为服务集合。生存期是由DI容器管理的,因此,如果您处置了客户机,但随后将其注入到某个对象中,您将得到一个
ObjectDisposedException
。让容器处理垃圾


这实际上是对
IDisposable
类的常见混淆。如果您的类本身拥有依赖项,您个人应该只实现
IDisposable
。如果注入了它的所有依赖项,则不应实现
IDisposable
,因为它不拥有任何需要处理的内容。同样,您不应该处理注入类中的任何内容,因为它不拥有这些依赖项。只处理你特别新买的东西。如果您没有看到关键字
new
,您可能不应该进行处理。

调用
Dispose
方法不是必需的,但是如果出于某些原因需要,您仍然可以调用它

证明:

不需要处置客户。Dispose取消传出请求,并保证在调用Dispose后无法使用给定的HttpClient实例。IHttpClientFactory跟踪和处置HttpClient实例使用的资源。HttpClient实例通常可以被视为不需要处理的.NET对象

检查:

公共HttpClient CreateClient(字符串名称) { if(name==null) { 抛出新ArgumentNullException(nameof(name)); } var handler=CreateHandler(名称); var client=新的HttpClient(handler,disposeHandler:false); var options=_optionsMonitor.Get(名称); 对于(var i=0;i
HttpMessageHandler
的实例存储
HttpClient
的非托管资源。在经典场景中,
HttpClient
创建
HttpMessageHandler
的实例,并在自身进行处理时对其进行处理

您可以在上面的代码中看到,
HttpClient
的不同实例共享
HttpMessageHandler
的单个实例,并且不处理它(
disposeHandler:false


因此,
HttpClient.Dispose
的调用不起任何作用。但这并不危险。

查看这篇文章,它解释了factory@Nkosi如何处理客户机是的,我已经读过了。但是,我找到了一些与我问题中最后一个代码片段非常相似的代码,我想知道是否需要修复它。这有点让人困惑,因为客户端不是通过DI容器检索的。工厂是通过DI容器检索的。但是httpClientFactory.CreateClient(someServiceName)中的命名似乎暗示您需要重新创建工厂,所以这是令人困惑的部分。我和@kierenjohnstone在一起,资源是否更新并不重要,重要的是你是否控制了它的生命周期。在工厂的情况下,工厂进行实例化,它控制生命周期,而不是您。这就是重点。只处理属于您的资源。@ChrisPratt如果C#或.NET包含某种对象生存期和所有权的语义以防止这种混淆,您是否同意这一点?即使是简单的界面(例如
IDisposableHahahNotReally
)或通过智能指针类型的对象引用对象,例如
OwnedObject.Instance
借用对象.Value
)。@ChrisPratt我认为这并不重要。我记得在一期关于ASP.NET回购协议的GitHub中读到,HttpClientHandler不能被处置。当您处置HttpClient(由如上所述的工厂创建)时,处理程序在处置HttpClient时“告诉”客户端不要处置它。因此,使用(var client=\u httpClientFactory.CreateClient())
,这样的代码根本没有问题。(我想):)