Unsere Web-App läuft in .Net Framework 4.0. Die Benutzeroberfläche ruft Controller-Methoden über Ajax-Aufrufe auf.
Wir müssen REST Service von unserem Lieferanten in Anspruch nehmen. Ich bewerte die beste Möglichkeit, REST Service in .Net 4.0 aufzurufen. Die REST erfordert das Standardauthentifizierungsschema und kann Daten sowohl in XML als auch in JSON zurückgeben. Es ist nicht erforderlich, große Datenmengen hoch- oder herunterzuladen, und ich sehe in Zukunft nichts. Ich habe mir einige Open-Source-Code-Projekte angesehen für REST Verbrauch und fand keinen Wert in denen, um zusätzliche Abhängigkeit im Projekt zu rechtfertigen. Begann WebClient
und HttpClient
auszuwerten. Ich lud HttpClient für .Net 4.0 von NuGet.
Ich habe nach Unterschieden zwischen WebClient
und HttpClient
und diese Seite gesucht und erwähnt, dass ein einzelner HttpClient gleichzeitige Aufrufe verarbeiten kann und aufgelöste DNS-, Cookie-Konfiguration und Authentifizierung wiederverwenden kann. Ich sehe noch keine praktischen Werte, die wir aufgrund der Unterschiede gewinnen könnten.
Ich habe einen schnellen Leistungstest durchgeführt, um herauszufinden, wie WebClient
(Synchronisierungsaufrufe), HttpClient
(Synchronisierung und Asynchronisierung) ausgeführt werden. und hier sind die Ergebnisse:
Verwenden derselben HttpClient
-Instanz für alle Anforderungen (min - max)
WebClient-Synchronisierung: 8 ms - 167 ms
HTTP-Client-Synchronisierung: 3 ms - 7228 ms
HttpClient async: 985 - 10405 ms
Verwenden eines neuen HttpClient
für jede Anfrage (min - max)
WebClient-Synchronisierung: 4 ms - 297 ms
HTTP-Client-Synchronisierung: 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
gegenüber WebClient
?HttpClient
besser als die von WebClient
? Aus den Testergebnissen geht hervor, dass die Synchronisierungsaufrufe von WebClient
eine bessere Leistung erbringen.HttpClient
eine bessere Wahl für das Design sein, wenn wir ein Upgrade auf .Net 4.5 durchführen? Leistung ist der entscheidende Designfaktor.Ich lebe sowohl in der F # - als auch in der Web-API-Welt.
Mit der Web-API passiert eine Menge Gutes, insbesondere in Form von Message-Handlern für die Sicherheit usw.
Ich weiß, meine Meinung ist nur eine, aber Ich würde die Verwendung von HttpClient
nur für zukünftige Arbeiten empfehlen . Vielleicht gibt es eine Möglichkeit, einige der anderen Teile, die aus System.Net.Http
ohne diese Assembly direkt zu verwenden, aber ich kann mir nicht vorstellen, wie das zu diesem Zeitpunkt funktionieren würde.
Apropos Vergleich dieser beiden
+--------------------------------------------+--------------------------------------------+
| WebClient | HttpClient |
+--------------------------------------------+--------------------------------------------+
| Available in older versions of .NET | .NET 4.5 only. Created to support the |
| | growing need of the Web API REST calls |
+--------------------------------------------+--------------------------------------------+
| WinRT applications cannot use WebClient | HTTPClient can be used with WinRT |
+--------------------------------------------+--------------------------------------------+
| Provides progress reporting for downloads | No progress reporting for downloads |
+--------------------------------------------+--------------------------------------------+
| Does not reuse resolved DNS, | Can reuse resolved DNS, cookie |
| configured cookies | configuration and other authentication |
+--------------------------------------------+--------------------------------------------+
| You need to new up a WebClient to | Single HttpClient can make concurrent |
| make concurrent requests. | requests |
+--------------------------------------------+--------------------------------------------+
| Thin layer over WebRequest and | Thin layer of HttpWebRequest and |
| WebResponse | HttpWebResponse |
+--------------------------------------------+--------------------------------------------+
| Mocking and testing WebClient is difficult | Mocking and testing HttpClient is easy |
+--------------------------------------------+--------------------------------------------+
| Supports FTP | No support for FTP |
+--------------------------------------------+--------------------------------------------+
| Both Synchronous and Asynchronous methods | All IO bound methods in |
| are available for IO bound requests | HTTPClient are asynchronous |
+--------------------------------------------+--------------------------------------------+
Wenn Sie .NET 4.5 verwenden, verwenden Sie die asynchrone Funktion von HttpClient, die Microsoft den Entwicklern bereitstellt. HttpClient ist sehr symmetrisch zu den Server-Brüdern des HTTP, das sind HttpRequest und HttpResponse.
Update: 5 Gründe für die Verwendung der neuen HttpClient-API:
Referenz
C # 5.0 Joseph Albahari
(Channel9 - Video Build 2013)
Fünf gute Gründe, die neue HttpClient-API für die Verbindung zu Webdiensten zu verwenden
HttpClient ist die neuere der APIs und bietet die Vorteile von
Wenn Sie einen Webdienst schreiben, der REST Aufrufe an andere Webdienste ausführt, sollten Sie für alle Ihre REST Aufrufe ein asynchrones Programmiermodell verwenden Sie möchten wahrscheinlich auch den neuesten C # -Compiler verwenden, der async/await-Unterstützung bietet.
Hinweis: Es ist nicht performanter AFAIK. Es ist wahrscheinlich etwas ähnlich performant, wenn Sie einen fairen Test erstellen.
Erstens bin ich keine Autorität für WebClient vs. HttpClient. Zweitens deuten Ihre obigen Kommentare darauf hin, dass WebClient NUR synchronisiert ist, während HttpClient beides ist.
Ich habe einen kurzen Leistungstest durchgeführt, um herauszufinden, wie die Leistung von WebClient (Synchronisierungsaufrufe), HttpClient (Synchronisierung und Asynchronisierung) ist. und hier sind die Ergebnisse.
Ich sehe das als einen großen Unterschied, wenn ich an die Zukunft denke, d. H. An lang laufende Prozesse, ansprechende Benutzeroberfläche usw.