.NET Framework 4.5中的System.Net.Http.HttpClient和System.Net.Http.HttpClientHandler实现了IDisposable(通过System.Net.Http.HttpMessageInvoker).
该using声明文件说:
通常,当您使用IDisposable对象时,您应该在using语句中声明并实例化它.
这个答案使用了这种模式:
var baseAddress = new Uri("http://example.com");
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("foo", "bar"),
new KeyValuePair<string, string>("baz", "bazinga"),
});
cookieContainer.Add(baseAddress, new Cookie("CookieName", "cookie_value"));
var result = client.PostAsync("/test", content).Result;
result.EnsureSuccessStatusCode();
}
Run Code Online (Sandbox Code Playgroud)
但是微软最明显的例子并没有Dispose()明确地或隐含地调用.例如:
HttpClientWebAPI客户端的生命周期应该是多少?为多个调用
设置一个实例是否更好HttpClient?
创建和处理HttpClient每个请求的开销是多少,如下面的示例所示(摘自http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from- a-net-client):
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:9000/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// New code:
HttpResponseMessage response = await client.GetAsync("api/products/1");
if (response.IsSuccessStatusCode)
{
Product product = await response.Content.ReadAsAsync<Product>();
Console.WriteLine("{0}\t${1}\t{2}", product.Name, product.Price, product.Category);
}
}
Run Code Online (Sandbox Code Playgroud) 在我可以找到的所有示例中HttpClient,它用于一次性呼叫.但是,如果我有一个持久的客户端情况,可以同时进行多个请求怎么办?基本上,client.PostAsync对同一个实例一次调用2个线程是安全的HttpClient.
我不是在寻找实验结果.作为一个工作示例可能只是一个侥幸(并且持久的),一个失败的例子可能是一个错误的配置问题.理想情况下,我正在寻找HttpClient中并发处理问题的一些权威答案.
我无法相信我仍然对此感到困惑但是,无论如何,让我们最终指出:
我有一个类覆盖OnPaint来做一些绘图.为了加快速度,我在构造函数中预先创建了笔,画笔等,以便OnPaint不需要继续创建和处理它们.
现在,我确保我总是处理这些对象,但我感觉我不需要,因为尽管它们实现了IDisposable,但它们都是托管对象.
它是否正确?
感谢所有的答案,这个问题肯定已被钉上了.
我很高兴我一直保持警惕,总是使用'使用',所以我不需要经历所有的代码检查.我只想清楚我不是一个毫无意义的用户.
顺便说一句,我确实有一个奇怪的情况,最近,我不得不更换一个使用块并手动调用dispose!我会把它挖出来并创造一个新问题.
以下两种设置 HttpClient 的场景有什么区别吗?
我应该选择其中一种而不是另一种吗?
键入的客户端:
public class CatalogService
{
private readonly HttpClient _httpClient;
public CatalogService(HttpClient httpClient) {
_httpClient = httpClient;
}
public async Task<string> Get() {
var response = await _httpClient.GetAsync();
....
}
public async Task Post() {
var response = await _httpClient.PostAsync();
...
}
}
// Startup.cs
//Add http client services at ConfigureServices(IServiceCollection services)
services.AddHttpClient<ICatalogService, CatalogService>();
Run Code Online (Sandbox Code Playgroud)
IHttpClientFactory:
public class CatalogService
{
private readonly IHttpClientFactory _factory;
public CatalogService(IHttpClientFactory factory) {
_factory = factory;
}
public async Task<string> Get() {
var …Run Code Online (Sandbox Code Playgroud) c# async-await dotnet-httpclient asp.net-core httpclientfactory
我对 ASP.NET 核心依赖注入容器有疑问。这个问题专门针对ASP.NET core 3.1。
基本上,我问自己,是否注入类型的HTTP客户端内部托管服务创建一个所谓的俘虏依赖于依赖注入的条款。
我试图描绘的场景如下:
public interface IStudentsApiClient
{
Task<IEnumerable<Student>> GetAll(CancellationToken cancellationToken);
}
public class StudentsApiClient: IStudentsApiClient
{
private readonly HttpClient _httpClient;
public StudentsApiClient(HttpClient httpClient)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
}
public async Task<IEnumerable<Student>> GetAll(CancellationToken cancellationToken)
{
// call a GET endpoint to retrieve all the students from a third party api...
}
}
public class StudentsPollingHostedService: BackgroundService
{
private readonly IStudentsApiClient _apiClient;
public StudentsPollingHostedService(IStudentsApiClient apiClient)
{ …Run Code Online (Sandbox Code Playgroud) c# dependency-injection ioc-container .net-core asp.net-core
我没有找到有关它的文档,我认为我当前的解决方案不是最佳的,因为处理程序生命周期不是由HttpClientFactory管理的:
var proxiedHttpClientHandler = new HttpClientHandler() { Proxy = httpProxy };
_createHttpClient = () => HttpClientFactory.Create(proxiedHttpClientHandler);
Run Code Online (Sandbox Code Playgroud)
有更好的解决方案吗?
c# ×5
.net ×3
.net-core ×2
asp.net-core ×2
idisposable ×2
.net-4.5 ×1
asp.net ×1
async-await ×1
c#-4.0 ×1
concurrency ×1
using ×1
web-services ×1