Singleton httpclient vs创建新的httpclient请求

我想在我的Xamarin.Forms移动应用程序中使用HttpClient创建web服务层。

  1. 没有单一模式
  2. 单身模式

一种方法中,我在移动应用程序发出的每个新请求中创建新的http客户端对象。

这是我的代码

  public HttpClient GetConnection() { HttpClient httpClient = new HttpClient(); httpClient.BaseAddress = new Uri(baseAddress); httpClient.Timeout = System.TimeSpan.FromMilliseconds(timeout); return httpClient; } 

发布请求代码

  public async Task PostAsync(String url, TRequest requestData) { HttpClient client = GetConnection(); String responseData = null; if (client != null) { String serializedObject = await Task.Run(() => JsonConvert.SerializeObject(requestData, _jsonSerializerSettings)); var jsonContent = new StringContent(serializedObject, System.Text.Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.PostAsync(new Uri(url, UriKind.Relative), jsonContent); responseData = await HandleResponse(response); return await Task.Run(() => JsonConvert.DeserializeObject(responseData, _jsonSerializerSettings)); } else { throw new NullReferenceException("NullReferenceException @ PostAsync httpclient is null WebRequest.cs"); } } 

客户端将使用以下代码来执行请求

 new LoginService(new WebRequest()).UserLogin(userRequest); 

实现IWebRequest内部类

 _webRequest.PostAsync(Constants.USER_LOGIN, userRequest); 

第二种方法中,我在这里重新使用每个新请求中的相同http客户端对象,我的单例类也是线程安全的。

 private static readonly Lazy lazy = new Lazy(() => new HttpService()); public static HttpService Instance { get { return lazy.Value; } } private HttpClient getConnection() { client = new HttpClient(); client.Timeout = System.TimeSpan.FromMilliseconds(timeout); //client.MaxResponseContentBufferSize = 500000; client.BaseAddress = new Uri(baseAddress); return client; } 

发布请求代码

 public Task sendData(String url,String jsonData) { var jsonContent = new StringContent(jsonData, System.Text.Encoding.UTF8, "application/json"); return getConnection().PostAsync(new Uri(url, UriKind.Relative), jsonContent); } 

客户端将使用以下代码来执行

 HttpService.Instance.sendData(...) 

我通过Web浏览了许多像RestSharp这样的库只是为了探索最好的,我发现他们中的大多数都在为每个请求创建新对象。 所以我很困惑哪种模式最适合。

Singleton是使用HttpClient的正确方法。 有关详细信息,请参阅此文章。

Microsoft docs声明:

HttpClient旨在实例化一次,并在应用程序的整个生命周期中重复使用。 为每个请求实例化一个HttpClient类将耗尽重负载下可用的套接字数量。 这将导致SocketException错误。 下面是一个正确使用HttpClient的示例。

事实上,我们在申请中发现了这一点。 我们的代码可能会在foreach循环中产生数百个API请求,并且对于每次迭代,我们创建了一个包含在usingHttpClient 。 我们很快就开始从我们的MongoClient获得红色鲱鱼错误,说它已经超时尝试连接到数据库。 在阅读链接文章后,我们发现即使在处理了HttpClient ,也意识到我们正在耗尽可用的套接字。

唯一需要注意的是, DefaultRequestHeadersBaseAddress类的东西将应用于使用HttpClient的任何地方。 作为单身人士,这可能贯穿整个应用程序。 您仍然可以在应用程序中创建多个HttpClient实例,但请注意,每次执行时,它们都会创建一个新的连接池,因此应该谨慎创建。

正如hvaughan3所指出的,您也无法更改HttpClient使用的HttpMessageHandler实例,因此如果这对您很重要,则需要对该处理程序使用单独的实例。

虽然HttpClient应该被重用,但这并不一定意味着我们必须使用单例来组织我们的代码。 请参考我的答案 。

PS:不确定我是否应该在这里复制并粘贴答案。 让我知道。

正如其他人提到的,大多数HttpClient应该用作单例,但是有一个例外 – 当你使用HTTP long polling技术时,你不应该使用HttpClient作为单例,因为你将阻止其他请求执行。

对于长轮询请求,您应该创建单独的HttpClient