可重用的 HttpClient 实例与静态变量(在多个线程中大量使用)?
Posted
技术标签:
【中文标题】可重用的 HttpClient 实例与静态变量(在多个线程中大量使用)?【英文标题】:Reusable HttpClient instance vs static variable (Heavily used in multiple threads)? 【发布时间】:2017-10-25 18:47:28 【问题描述】:我目前有一个HttpClient
的实例变量,它在实例方法中用于下载图像。该方法总是在Task.Run()
中调用。
此方法可以在一分钟内调用数千次,并且不会崩溃或产生任何错误。但我只是想知道如果我切换到 static HttpClient
会有什么好处(如果有的话),除了可能更安全之外。
这里有一些上下文代码:
HttpClient client = new HttpClient(); // Make this static?
// Always called in a Task.Run(() => DownloadImage(Obj));
public async void DownloadImage(Object obj)
FormUrlEncodedContent formContent = GetFormContent(Obj);
HttpResponseMessage Result = await client.PostAsync("URL", formContent).ConfigureAwait(false);
byte[] Data = Result.Content.ReadAsByteArrayAsync().Result;
StaticClass.Images[Obj.ID] = ImageSource.FromStream(() => new MemoryStream(Data));
formContent.Dispose();
Result.Dispose();
【问题讨论】:
如果DownloadImage
被调用在这个代码所在的任何类的同一个实例上,那么没有区别
@Jonesopolis 是的,就是这样。
有谁知道什么时候适合制作一个经常重用的静态 HttpClient ?这篇文章建议这样做:aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
HttpClient is fully thread-safe and reentrant,因此将其设为静态变量实际上是与其交互的首选方式。
什么是temp
?为什么不是你的DownloadImage
async
?
【参考方案1】:
否
由于您没有使用async
版本并且您正在调用ReadAsByteArrayAsync().Result
,因此您很可能会陷入死锁。
推荐
以下是最推荐的方式,
static HttpClient client = new HttpClient ();
public async Task DownloadImage(Object obj)
using(FormUrlEncodedContent formContent = GetFormContent(Obj))
using(HttpResponseMessage Result = await
client.PostAsync("URL", formContent)
.ConfigureAwait(false))
byte[] Data = await Result.Content.ReadAsByteArrayAsync();
StaticClass.Images[Obj.ID] = ImageSource.FromStream(
() => new MemoryStream(Data));
同样不要调用Dispose
,使用using
块,如果抛出异常,Dispose
将不会被执行,using
块将正确Dispose
即使出现异常。
只要所有一次性用品都包裹在using
中,async await
使用得当,HttpClient
将在单个静态实例中表现最佳。
【讨论】:
【参考方案2】:HttpClient 被微软用作静态对象。即使每次启动它的时间都很短,因为可能会出现其他问题。 他的链接包含一个简单的实现: https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client.
由于您将在更多情况下使用客户端而不是简单地获取图像,因此我建议您使用具有静态方法(如果可能的话,异步)的类用于 get/post/put/delete,您将在其中动态插入方法名称和对象.
【讨论】:
以上是关于可重用的 HttpClient 实例与静态变量(在多个线程中大量使用)?的主要内容,如果未能解决你的问题,请参考以下文章