HttpClient和HttpclientHandler处置或不处置,这是一个问题



我正在寻找优化我的代码…我有一些API与早期相同的结构的客户端和处理程序。

但是我有一些关于处理的问题。

我已经阅读了using语句自动处置资源(这里是HttpClient和HttpClientHandler)。

我可以在这里重写我的代码吗?

public static async Task<IEnumerable<T>> deletePostsAsync<T>(IEnumerable<string> urls) where T : BaseReturnValues
{
var httpClientHandler = new HttpClientHandler
{
Proxy = new WebProxy(proxy, true),
UseProxy = IsProxySelected
};
using (var client = new HttpClient(httpClientHandler))
{
client.BaseAddress = new Uri(URI);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add(Head.key, Head.apikey);
var tasks = urls.Select(async url => await DeleteAsync<T>(client, url).ConfigureAwait(false));
var result = await Task.WhenAll(tasks).ConfigureAwait(false);
return result!;
}
async Task<U> DeleteAsync<U>(HttpClient client, string url) where U : BaseReturnValues
{
var statusCode = -1;
var json = "_";
var isSuccess = false;
try
{
using (HttpResponseMessage response = await client.DeleteAsync(url).ConfigureAwait(false))
{
statusCode = (Int32)response.StatusCode;
json = await response.Content.ReadAsStringAsync();
isSuccess = response.IsSuccessStatusCode;
}
}
catch (Exception ex)
{
//something to catch
}
:
return record;
}
}

这段代码没有问题吗?处理资源总是完成吗?

public static async Task<IEnumerable<T>> deletePostsAsync<T>(IEnumerable<string> urls) where T : BaseReturnValues
{
using (var client = SetClientSettings())
{
var tasks = urls.Select(async url => await DeleteAsync<T>(client, url).ConfigureAwait(false));
var result = await Task.WhenAll(tasks).ConfigureAwait(false);
return result!;
}
async Task<U> DeleteAsync<U>(HttpClient client, string url) where U : BaseReturnValues
{
:
:
return record;
}
}
public static Httpclient SetClientSettings()
{
var httpClientHandler = new HttpClientHandler
{
Proxy = new WebProxy(proxy, true),
UseProxy = IsProxySelected
};
var client = new HttpClient(httpClientHandler);
client.BaseAddress = new Uri(URI);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add(Head.key, Head.apikey);
return client;
}

所以我已经创建了一个方法SetClientSettings和这个方法创建客户端,clienthandler,添加一些头到客户端和返回客户端。

var httpClientHandler = new HttpClientHandler
{
Proxy = new WebProxy(proxy, true),
UseProxy = IsProxySelected
};
using (var client = new HttpClient(httpClientHandler))
{
client.BaseAddress = new Uri(URI);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add(Head.key, Head.apikey);
var tasks = urls.Select(async url => await DeleteAsync<T>(client, url).ConfigureAwait(false));
var result = await Task.WhenAll(tasks).ConfigureAwait(false);
return result!;
}

真的等价于??:

using (var client = SetClientSettings())
{
var tasks = urls.Select(async url => await DeleteAsync<T>(client, url).ConfigureAwait(false));
var result = await Task.WhenAll(tasks).ConfigureAwait(false);
return result!;
}

您的两段代码不是等价的。有一个小小的区别,对于第一个代码片段,即使下面几行(例如client.BaseAddress = new Uri(URI);client.DefaultRequestHeaders.Clear();)失败,您也将处理客户端。哪个更好。为了在SetClientSettings中实现这一点,您需要在例外情况下将所有内容包装到try except.Dispose()中。


我已经阅读了using语句自动处置资源(这里是HttpClient和HttpClientHandler)。

using语句将此转换为

using (var instance = something)
{
// body
}

var instance = something;
try
{
// body
}
finally
{
if (instance != null)
{
instance.Dispose();
}
}

这就是它的全部功能。它是一种语法糖。

所以在你的特殊情况下,using语句将确保.Dispose()在HttpClient上被调用,不管是否抛出异常。

现在,我们必须处理HttpClient吗?他们说我们必须这么做,我们没有理由不相信。实际上,HttpClient在引擎盖下保存套接字,在完成时必须手动关闭。因此,是的,您应该在完成。

时始终处理HttpClient

。也就是说,你能做的最好的事情是在你的应用程序期间拥有一个单例HttpClient,并重用它。你可以根据你的需要调整它(例如配置它使用池连接)以获得最大的效率。在这种情况下,您根本不处理它。

注意:你不必担心处理HttpClientHandler。默认情况下,HttpClient会在它自己被释放时释放它。这种行为可以通过使用不同的构造函数来修改。

是的,你写的代码彼此是等价的。在HttpClient构造函数中有一个不处置消息处理程序的选项-默认情况下,它被设置为true。无论如何,正如已经建议的那样,您根本不必处理HTTP客户机。这是有原因的

有很多关于使用HttpClient的最佳实践的好文章。试着搜索IHttpClientFactory.

相关内容

最新更新