更新时间:2023-02-16 20:47:16
我住在这两个F#和Web API的世界。
有很多的好东西发生在Web API,特别是在安全性消息处理程序等。
的形式我知道我只有一个意见,但我只推荐使用的HttpClient
为今后的任何工作。也许有一些方法来利用一些其他的作品走出 System.Net.Http
而不直接使用该程序集,但我无法想象如何将工作在这个时候。
说起比较这两个
如果您使用的是.NET 4.5,请不要使用异步善良与HttpClient的,微软提供给开发商。 HttpClient的是非常对称的HTTP那些Htt的prequest和Htt的presponse。
服务器端的弟兄更新:5理由使用新的HttpClient API
强类型头。 共享缓存,cookie和证书 访问饼干和共享饼干 控制缓存与共享缓存。 注入你code模块插入到ASP.NET管道。清洁和模块化code。
参考
C#5.0约瑟夫阿尔巴哈利
(Channel9的 - 视频生成2013)
五大理由使用新的HttpClient API连接到Web服务一>
Our web app is running in .Net Framework 4.0. The UI calls controller methods through ajax calls.
We need to consume REST service from our vendor. I am evaluating the best way to call REST service in .Net 4.0. The REST service requires Basic Authentication Scheme and it
can return data in both XML and JSON. There is no requirement for uploading/downloading huge data and I don't see anything in future. I took a look at few open source code projects for REST consumption and didn't find any value in those to justify additional dependency in the project. Started to evaluate WebClient
and HttpClient
. I downloaded HttpClient for .Net 4.0 from NuGet.
I searched for differences between WebClient
and HttpClient
and this site mentioned that single HttpClient can handle concurrent calls and it can reuse resolved DNS, cookie config and authentication. I am yet to see practical values that we may gain due to the differences.
I did a quick performance test to find how WebClient
(sync calls), HttpClient
(sync and async) perform. and here are the results:
Using same HttpClient
instance for all the requests (min - max)
WebClient sync: 8 ms - 167 ms
HttpClient sync: 3 ms - 7228 ms
HttpClient async: 985 - 10405 ms
Using a new HttpClient
for each request (min - max)
WebClient sync: 4 ms - 297 ms
HttpClient sync: 3 ms - 7953 ms
HttpClient async: 1027 - 10834 ms
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 static void Main(string[] args)
{
#region "Trace"
Trace.Listeners.Clear();
TextWriterTraceListener twtl = new TextWriterTraceListener(
"C:\\Temp\\REST_Test.txt");
twtl.Name = "TextLogger";
twtl.TraceOutputOptions = TraceOptions.ThreadId | TraceOptions.DateTime;
ConsoleTraceListener ctl = new ConsoleTraceListener(false);
ctl.TraceOutputOptions = TraceOptions.DateTime;
Trace.Listeners.Add(twtl);
Trace.Listeners.Add(ctl);
Trace.AutoFlush = true;
#endregion
int batchSize = 1000;
ParallelOptions parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = batchSize;
ServicePointManager.DefaultConnectionLimit = 1000000;
Parallel.For(0, batchSize, parallelOptions,
j =>
{
Stopwatch sw1 = Stopwatch.StartNew();
GetDataFromHttpClientAsync<List<AHNData>>(sw1);
});
Parallel.For(0, batchSize, parallelOptions,
j =>
{
Stopwatch sw1 = Stopwatch.StartNew();
GetDataFromHttpClientSync<List<AHNData>>(sw1);
});
Parallel.For(0, batchSize, parallelOptions,
j =>
{
using (WebClient client = new WebClient())
{
Stopwatch sw = Stopwatch.StartNew();
byte[] arr = client.DownloadData(_url);
sw.Stop();
Trace.WriteLine("WebClient Sync " + sw.ElapsedMilliseconds);
}
});
Console.Read();
}
public static T GetDataFromWebClient<T>()
{
using (var webClient = new WebClient())
{
webClient.BaseAddress = _url;
return JsonConvert.DeserializeObject<T>(
webClient.DownloadString(_url));
}
}
public static void GetDataFromHttpClientSync<T>(Stopwatch sw)
{
HttpClient httpClient = new HttpClient();
var response = httpClient.GetAsync(_url).Result;
var obj = JsonConvert.DeserializeObject<T>(
response.Content.ReadAsStringAsync().Result);
sw.Stop();
Trace.WriteLine("HttpClient Sync " + sw.ElapsedMilliseconds);
}
public static void GetDataFromHttpClientAsync<T>(Stopwatch sw)
{
HttpClient httpClient = new HttpClient();
var response = httpClient.GetAsync(_url).ContinueWith(
(a) => {
JsonConvert.DeserializeObject<T>(
a.Result.Content.ReadAsStringAsync().Result);
sw.Stop();
Trace.WriteLine("HttpClient Async " + sw.ElapsedMilliseconds);
}, TaskContinuationOptions.None);
}
}
}
HttpClient
over WebClient
?HttpClient
concurrency better than WebClient
? From the test results, I see WebClient
sync calls perform better.HttpClient
be a better design choice if we upgrade to .Net 4.5? Performance is the key design factor.
I live in both the F# and Web API worlds.
There's a lot of good stuff happening with Web API, especially in the form of message handlers for security, etc.
I know mine is only one opinion, but I would only recommend use of HttpClient
for any future work. Perhaps there's some way to leverage some of the other pieces coming out of System.Net.Http
without using that assembly directly, but I cannot imagine how that would work at this time.
Speaking of comparing these two
If you’re using .NET 4.5, please do use the async goodness with HttpClient that Microsoft provides to the developers. HttpClient is very symmetrical to the server side brethren of the HTTP those are HttpRequest and HttpResponse.
Update: 5 Reasons to use new HttpClient API
Strongly typed headers. Shared Caches, cookies and credentials Access to cookies and shared cookies Control over caching and shared cache. Inject your code module into the ASP.NET pipeline. Cleaner and modular code.
Reference
C# 5.0 Joseph Albahari
(Channel9 — Video Build 2013)
Five Great Reasons to Use the New HttpClient API to Connect to Web Services