Notre application web est en cours d'exécution .Net Framework 4.0. L'INTERFACE utilisateur des appels de méthodes de contrôleur à travers des appels ajax.
Nous avons besoin de consommer de REPOS, service de notre fournisseur. Je suis évaluer la meilleure façon de faire des appels de service REST en .Net 4.0. Le RESTE du service nécessite l'Authentification de Base Régime et il
peut renvoyer des données en XML et JSON. Il n'est pas nécessaire pour le téléchargement/téléchargement de données énorme et je ne vois rien dans l'avenir. J'ai pris un coup d'oeil à l'open source, les projets de code pour le REPOS de la consommation et de ne pas trouver une valeur dans ceux de justifier de nouvelles dépendance dans le projet. De commencer à évaluer WebClient
et HttpClient
. J'ai téléchargé HttpClient .Net 4.0 à partir de NuGet.
J'ai cherché pendant des différences entre WebClient
et HttpClient
et ce site mentionné que seul HttpClient peut gérer les appels simultanés et il peut réutiliser résolu DNS, témoin de config et d'authentification. Je suis encore à voir les valeurs pratiques que nous pouvons avoir, en raison des différences.
J'ai fait un rapide test de performance de trouver comment WebClient
(synchronisation des appels), HttpClient
(synchronisation et asynchrone) effectuer. et voici les résultats:
En utilisant le même HttpClient
exemple pour toutes les demandes (min - max)
WebClient sync: 8 ms - 167 ms
HttpClient sync: 3 ms - ms 7228
HttpClient async: 985 - 10405 ms
À l'aide d'un nouveau HttpClient
pour chaque demande (min - max)
WebClient sync: 4 ms - ms 297
HttpClient sync: 3 ms - ms 7953
HttpClient async: 1027 - 10834 ms
Code
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);
}
}
}
Mes Questions
- Le RESTE des appels de retour dans 3-4s qui est acceptable. Les appels au REPOS service sont initiées dans les méthodes du controller qui est appelé à partir de les appels ajax. Pour commencer, les appels exécuter dans un thread différent et ne pas bloquer l'INTERFACE utilisateur. Donc, puis-je simplement s'en tenir à la synchronisation des appels?
- Le code ci-dessus a été exécuté dans mon localbox. En prod, d'installation, de DNS et proxy
de recherche seront impliqués. Est-il un avantage de l'utilisation de
HttpClient
surWebClient
? - Est -
HttpClient
de la simultanéité de mieux que de WebClient ? Des résultats du test, je voisWebClient
de la synchronisation des appels de mieux performer. - Va
HttpClient
être un meilleur choix de conception si nous avons de mise à niveau .Net 4.5? La Performance est la clé de la conception de facteur.