.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()明确地或隐含地调用.例如:
这是我到目前为止的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System;
using System.Net.Http;
using System.Web;
using System.Net;
using System.IO;
namespace ConsoleProgram
{
public class Class1
{
private const string URL = "https://sub.domain.com/objects.json?api_key=123";
private const string DATA = @"{""object"":{""name"":""Name""}}";
static void Main(string[] args)
{
Class1.CreateObject();
}
private static void CreateObject()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = DATA.Length;
StreamWriter requestWriter = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);
requestWriter.Write(DATA);
requestWriter.Close();
try {
WebResponse webResponse = request.GetResponse();
Stream webStream = …Run Code Online (Sandbox Code Playgroud) 我们的网络应用程序在.Net Framework 4.0中运行.UI通过ajax调用调用控制器方法.
我们需要从供应商处使用REST服务.我正在评估在.Net 4.0中调用REST服务的最佳方法.REST服务需要基本身份验证方案,它可以返回XML和JSON中的数据.没有要求上传/下载大量数据,我将来也看不到任何东西.我看了几个用于REST消费的开源代码项目,并没有找到任何值来证明项目中的额外依赖性.开始评估WebClient和HttpClient.我从NuGet下载了用于.Net 4.0的HttpClient.
我搜索了WebClient和之间的差异,HttpClient并且该网站提到单个HttpClient可以处理并发调用,它可以重用已解析的DNS,cookie配置和身份验证.我还没有看到由于差异我们可能获得的实用价值.
我做了一个快速的性能测试,以找到WebClient(同步调用),HttpClient(同步和异步)如何执行.以下是结果:
HttpClient对所有请求使用相同的实例(min - max)
WebClient同步:8毫秒 - 167毫秒
HttpClient同步:3毫秒 - 7228毫秒
HttpClient异步:985 - 10405毫秒
HttpClient为每个请求使用new (min - max)
WebClient同步:4毫秒 - 297毫秒
HttpClient同步:3毫秒 - 7953毫秒
HttpClient异步:1027 - 10834毫秒
public class AHNData
{
public int i;
public string str;
}
public class Program
{
public static HttpClient httpClient = new HttpClient();
private static readonly string _url = "http://localhost:9000/api/values/";
public …Run Code Online (Sandbox Code Playgroud) 在我可以找到的所有示例中HttpClient,它用于一次性呼叫.但是,如果我有一个持久的客户端情况,可以同时进行多个请求怎么办?基本上,client.PostAsync对同一个实例一次调用2个线程是安全的HttpClient.
我不是在寻找实验结果.作为一个工作示例可能只是一个侥幸(并且持久的),一个失败的例子可能是一个错误的配置问题.理想情况下,我正在寻找HttpClient中并发处理问题的一些权威答案.
我最近创建了一个用于测试HTTP调用吞吐量的简单应用程序,该应用程序可以以异步方式生成,而不是传统的多线程方法.
该应用程序能够执行预定义数量的HTTP调用,最后它显示执行它们所需的总时间.在我的测试期间,所有HTTP调用都发送到我的本地IIS服务器,并且他们检索了一个小文本文件(大小为12个字节).
下面列出了异步实现代码中最重要的部分:
public async void TestAsync()
{
this.TestInit();
HttpClient httpClient = new HttpClient();
for (int i = 0; i < NUMBER_OF_REQUESTS; i++)
{
ProcessUrlAsync(httpClient);
}
}
private async void ProcessUrlAsync(HttpClient httpClient)
{
HttpResponseMessage httpResponse = null;
try
{
Task<HttpResponseMessage> getTask = httpClient.GetAsync(URL);
httpResponse = await getTask;
Interlocked.Increment(ref _successfulCalls);
}
catch (Exception ex)
{
Interlocked.Increment(ref _failedCalls);
}
finally
{
if(httpResponse != null) httpResponse.Dispose();
}
lock (_syncLock)
{
_itemsLeft--;
if (_itemsLeft == 0)
{
_utcEndTime = DateTime.UtcNow;
this.DisplayTestResults();
}
}
} …Run Code Online (Sandbox Code Playgroud) 我已经编写了下面的代码来发送标题,发布参数.问题是我使用SendAsync,因为我的请求可以是GET或POST.如何将POST Body添加到此代码中,以便如果有任何帖子正文数据,则会在我发出的请求中添加它,如果它的简单GET或POST没有正文,则会以此方式发送请求.请更新以下代码:
HttpClient client = new HttpClient();
// Add a new Request Message
HttpRequestMessage requestMessage = new HttpRequestMessage(RequestHTTPMethod, ToString());
// Add our custom headers
if (RequestHeader != null)
{
foreach (var item in RequestHeader)
{
requestMessage.Headers.Add(item.Key, item.Value);
}
}
// Add request body
// Send the request to the server
HttpResponseMessage response = await client.SendAsync(requestMessage);
// Get the response
responseString = await response.Content.ReadAsStringAsync();
Run Code Online (Sandbox Code Playgroud) 我目前正在使用System.Net.Http.HttpClient进行跨平台支持.
我读到,为每个请求实例化HttpClient对象并不是一个好习惯,并且应尽可能重用它.
现在我在为服务编写客户端库时遇到问题.某些API调用需要具有特定标头,有些必须不包含此特定标头.
似乎我只能操纵将随每个请求发送的"DefaultRequestHeaders".
实际发出请求时是否有一个选项,例如"client.PostAsync()"来修改仅针对特定请求的标头?
(信息:请求可以是多线程的).
提前致谢!
我很好奇这HttpClientFactory堂课的目的是什么.没有描述MSDN上存在的原因(参见链接).
有些Create方法有更专业的参数,但大多数我不知道没有参数的调用和普通的构造函数之间有什么区别.
var httpClient = HttpClientFactory.Create();
Run Code Online (Sandbox Code Playgroud)
VS
var httpClient = new HttpClient();
Run Code Online (Sandbox Code Playgroud)
在大多数示例中,我看到使用了new HttpClient(),没有任何using语句,即使HttpClient该类派生自IDisposable.
由于HttpClient该类源自IDisposable,工厂是否有一些池化或缓存?是否有性能优势,或者无关紧要?
我做了一些简单的测试比较和我发现的一些信息
单个HttpClient可以由多个请求共享,如果共享并且请求到达同一目的地,则多个请求可以重用WebRequest需要为每个请求重新创建连接的连接.
我还查阅了一些关于使用HttpClient示例的其他方法的文档
以下文章总结了高速NTLM身份验证的连接共享
HttpWebRequest.UnsafeAuthenticatedConnectionSharing
我尝试过的可能实现如下所示
一个)
private WebRequestHandler GetWebRequestHandler()
{
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(ResourceUriCanBeAnyUri, "NTLM", CredentialCache.DefaultNetworkCredentials);
WebRequestHandler handler = new WebRequestHandler
{
UnsafeAuthenticatedConnectionSharing = true,
Credentials = credentialCache
};
return handler;
}
using (HttpClient client = new HttpClient(GetWebRequestHandler(), false))
{
}
Run Code Online (Sandbox Code Playgroud)
B)
using (HttpClient client = new HttpClient)
{
}
Run Code Online (Sandbox Code Playgroud)
C)
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("some uri string")
Run Code Online (Sandbox Code Playgroud)
我将不胜感激任何帮助,让我了解应该采取哪种方法,以实现最大性能,最小化连接并确保安全性不受影响.
我正在尝试使用Xamarin.Forms移动应用程序中的HttpClient为webservice创建图层.
在第一种方法中,我在移动应用程序发出的每个新请求中创建新的http客户端对象.
这是我的代码
public HttpClient GetConnection()
{
HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(baseAddress);
httpClient.Timeout = System.TimeSpan.FromMilliseconds(timeout);
return httpClient;
}
Run Code Online (Sandbox Code Playgroud)
发布请求代码
public async Task<TResult> PostAsync<TRequest, TResult>(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 …Run Code Online (Sandbox Code Playgroud) c# ×8
.net ×4
httpclient ×4
.net-4.5 ×2
rest ×2
api ×1
async-await ×1
asynchronous ×1
c#-4.0 ×1
concurrency ×1
idisposable ×1
using ×1
webclient ×1
xamarin ×1