【发布时间】:2019-12-06 00:32:56
【问题描述】:
基于this article,我决定在我的项目中为我的HttpClient 创建单个实例,从它的consumer 向我的WebAPI 发送两个请求。另外为了终止连接,我决定使用this article 的解决方案。在使用单例发送两个请求后,我收到了这个异常:
System.InvalidOperationException:此实例已启动 一个或多个请求。
所以我决定使用this SO answer的界面和配置(类似)。一切似乎都运行良好,但是在运行 netstat.exe 之后,我注意到,对于我的 API 使用者,打开了两 (2) 个不同端口号的不同连接:
注意[::1]:49153 是我的WebAPI 端口,所以我假设[::1]:57612 和[::1]:57614 是为我的消费者 开放的。为什么?如果他们应该使用同一个客户端?
不应该像first mentioned article那样吗?
我的HttpClientFactory:
public interface IHttpClientFactory
{
HttpClient CreateClient();
}
public class HttpClientFactory : IHttpClientFactory
{
static AppConfig config = new AppConfig();
static string baseAddress = config.ConnectionAPI;
public HttpClient CreateClient()
{
var client = new HttpClient();
SetupClientDefaults(client);
return client;
}
protected virtual void SetupClientDefaults(HttpClient client)
{
//client.Timeout = TimeSpan.FromSeconds(30);
client.BaseAddress = new Uri(baseAddress);
client.DefaultRequestHeaders.ConnectionClose = true;
}
}
还有我的两种请求发送方式:
public async Task<bool> SendPostRequestAsync(string serializedData)
{
CallerName = _messageService.GetCallerName();
HttpResponseMessage response = new HttpResponseMessage();
Console.Write(MessagesInfo[CallerName]);
try
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, Config.ApiPostUri);
request.Content = new StringContent(serializedData, Encoding.UTF8, "application/json");
response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
if (response.IsSuccessStatusCode)
{
Console.WriteLine(MessagesResult[CallerName]); //success status
return true;
}
else
{
throw new Exception("Status code: " + response.StatusCode.ToString());
}
}
catch (Exception e)
{
_logger.Error(e.Message.ToString() + ", " + MessagesError[CallerName]);
CloseConnection();
return false;
}
}
和
public async Task<bool> SendGetRequestAsync()
{
CallerName = _messageService.GetCallerName();
HttpResponseMessage response = new HttpResponseMessage();
Console.Write(MessagesInfo[CallerName]);
try
{
response = await _httpClient.GetAsync(Config.ApiGetUri, HttpCompletionOption.ResponseHeadersRead);
if (response.IsSuccessStatusCode)
{
Console.WriteLine(MessagesResult[CallerName]); //success status
return true;
}
else
{
throw new Exception("Status code: " + response.StatusCode.ToString());
}
}
catch (Exception e)
{
_logger.Error(e.Message.ToString() + ", " + MessagesError[CallerName]);
CloseConnection();
return false;
}
}
连接关闭:
public void CloseConnection()
{
CallerName = _messageService.GetCallerName();
var sp = ServicePointManager.FindServicePoint(new Uri(Config.ConnectionAPI));
sp.ConnectionLeaseTimeout = 1 * 1000;
Console.WriteLine();
Console.WriteLine(MessagesResult[CallerName]);
}
【问题讨论】:
-
您可能希望考虑将
HttpClientFactory更改为存储HttpClient(在static Lazy中),以便它提供相同 @ 987654338@ 而不是旋转新的。
标签: c# singleton httprequest httpclient