当前位置: 首页 > 编程语言 > C#

ASP.NETMVC中HttpClientSingleton的实现分享

时间:2023-04-11 00:31:45 C#

ASP.NETMVC中HttpClientSingleton的实现看了这篇博文和www.asp.net上的官方说明:HttpClient被设计成一次实例化,再重新在应用程序的整个生命周期中使用。特别是在服务器应用程序中,为每个请求创建一个新的HttpClient实例会耗尽重负载下可用的套接字数。这将导致SocketException错误。我发现我们的代码在每次调用时都会处理HttpClient。我正在更新我们的代码以便我们重用HttClient,但我担心的是我们的工具不是线程安全的。这是新代码的当前草案:对于单元测试,我们为消费者调用的HttpClient实现了包装器:publicclassHttpClientWrapper:IHttpClient{privatereadonlyHttpClient_client;publicUriBaseAddress{get{return_client.BaseAddress;}设置{_client.BaseAddress=值;}}publicHttpRequestHeadersDefaultRequestHeaders{get{return_client.DefaultRequestHeaders;}}publicHttpClientWrapper(){_client=newHttpClient();}publicTaskSendAsync(HttpRequestMessagerequest,StringuserOrProcessName){IUnityContainercontainer=UnityCommon.GetContainer();ILogServicelogService=container.Resolve();logService.Log(ApplicationLogTypes.Debug,JsonConvert.SerializeObject(request),userOrProcessName);返回_client.SendAsync(请求);}#regionIDisposable支持privatebooldisposedValue=false;//检测冗余调用protectedvirtualvoidDispose(booldisposing){if(!disposedValue){if(disposing&&_client!=null){_client.Dispose();}disposedVa卢=真;}}publicvoidDispose(){Dispose(true);}#endregion}这是一个调用的服务:publicclassEnterpriseApiService:IEnterpriseApiService{privatestaticIHttpClient_client;staticEnterpriseApiService(){IUnityContainer容器=UnityCommon.GetContainer();IApplicationSettingServiceappSettingService=container.Resolve();_client=container.Resolve();}publicEnterpriseApiService(){}publicTaskCallApiAsync(Uriuri,HttpMethod方法,HttpContent内容,HttpRequestHeadersrequestHeaders,booladdJsonMimeAccept=true){IUnityContainercontainer=UnityCommon.GetContainer();HttpRequestMessage请求;_client.BaseAddress=newUri(uri.GetLeftPart(UriPartial.Authority));如果(addJsonMimeAccept)_client.DefaultRequestHeaders.Accept.Add(newMediaTypeWithQualityHeaderValue("application/json"));request=newHttpRequestMessage(方法,uri.AbsoluteUri);//删除了使用内容、requestHeaders和方法retur构建请求的逻辑n_client.SendAsync(request,UserOrProcessName);我的问题:这是重用HttpClient对象的合适方法吗?是否为EnterpriseApiService的所有实例共享静态_httpClient字段(填充静态构造函数)?我想确认,由于实例方法在调用CallApiAsync()时调用它,因此当对静态HttpClient进行更改时,例如“_client.DefaultRequestHeaders.Accept.Add(newMediaTypeWithQualityHeaderValue("application/json"))”这些值可能被调用的最后一个进程行“_client.SendAsync”覆盖?我担心在处理CallApiAsync()的过程中,静态实例将被更新。由于它调用SendAsync(),我们是否可以保证将响应映射回正确的调用方?我想确保响应不会转到另一个呼叫者。更新:因为我已经删除了USING语句,并且GarageCollection没有调用Dispose,所以我采用了在该方法中创建新实例的更安全的方法。要在线程的生命周期内重用HttpClient实例,需要对逻辑进行重大重写,因为该方法会为每次调用设置HttpClient属性。你真的想要一个实例吗?我不认为你想要一个应用程序范围的实例。您希望每个线程一个实例。否则你将无法获得出色的性能!此外,这将解决您的问题#3和#4,因为没有两个线程会同时访问同一个HttpClient。您不需要单例,只需将Container.Resolve与PerThreadLifetimeManager一起使用即可。对于那些有幸使用.NETCore的人来说,它相当简单。正如JohnWu所说的那样雄辩,你不需要单例,但每个请求都需要单例。因此,AddScoped()方法就是您所追求的。在您的ConfigureServices(IServiceCollectionservices)方法中:services.AddScoped();使用:公共类HomeController{readonlyHttpClient客户端;publicHomeController(HttpClientclient){this.client=client;}//控制器代码的其余部分}由于它调用SendAsync(),我们是否保证将响应映射回正确的调用方?我想确保响应不会转到另一个呼叫者。这将通过回调指针处理。它与将HttpClient用作单例无关。更多详情-https://stackoverflow.com/a/42307650/895724以上就是C#学习教程的全部内容:ASP.NETMVC中的HttpClientSingleton实现分享,如果对大家有用还需要了解更多关于C#学习教程,希望大家多多关注—本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: