हमारा वेब ऐप .Net फ्रेमवर्क 4.0 में चल रहा है। यूआई अजाक्स कॉल के माध्यम से नियंत्रक विधियों को कॉल करता है।
हमें अपने विक्रेता से REST सेवा का उपभोग करना होगा। मैं .net 4.0 में REST सेवा को कॉल करने के सर्वोत्तम तरीके का मूल्यांकन कर रहा हूं। REST सेवा के लिए मूल प्रमाणीकरण योजना की आवश्यकता होती है और यह XML और JSON दोनों में डेटा लौटा सकती है। विशाल डेटा अपलोड / डाउनलोड करने के लिए कोई आवश्यकता नहीं है और मुझे भविष्य में कुछ भी दिखाई नहीं देता है। मैंने REST की खपत के लिए कुछ खुले स्रोत कोड परियोजनाओं पर एक नज़र डाली और परियोजना में अतिरिक्त निर्भरता को सही ठहराने के लिए उनमें कोई मूल्य नहीं पाया। मूल्यांकन करने के लिए शुरू किया WebClient
और HttpClient
। मैंने NuGet से .net 4.0 के लिए HttpClient डाउनलोड किया।
मैंने और इस साइट के बीच के अंतरों की खोज की WebClient
और उल्लेख किया कि एकल HttpClient समवर्ती कॉल को संभाल सकता है और यह DNS, कुकी कॉन्फिग और ऑथेंटिकेशन को हल कर सकता है। मुझे उन व्यावहारिक मूल्यों को देखना बाकी है जिन्हें हम मतभेदों के कारण प्राप्त कर सकते हैं।HttpClient
मैंने यह पता लगाने के लिए एक त्वरित प्रदर्शन परीक्षण किया कि कैसे WebClient
(सिंक कॉल), HttpClient
(सिंक और एसिंक्स) प्रदर्शन करते हैं। और यहाँ परिणाम हैं:
HttpClient
सभी अनुरोधों के लिए एक ही उदाहरण का उपयोग करना (न्यूनतम - अधिकतम)
WebClient सिंक: 8 एमएस - 167 एमएस
HttpClient सिंक: 3 एमएस - 7228 एमएस
HttpClient async: 985 - 10405 एमएस
HttpClient
प्रत्येक अनुरोध के लिए एक नया प्रयोग करना (न्यूनतम - अधिकतम)
WebClient सिंक: ४ एमएस - २ ९
H एमएस HttpClient सिंक: ३ एमएस - p ९ ५३ एमएस
एचटीटीपी क्लाइंट async: १०२ 4 - १०34३४ एमएस
कोड
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);
}
}
}
मेरे सवाल
- REST कॉल 3-4s में लौटाता है जो स्वीकार्य है। नियंत्रक सेवा के लिए कॉल को नियंत्रक विधियों में शुरू किया जाता है जो कि अजाक्स कॉल से आह्वान किया जाता है। शुरू करने के लिए, कॉल एक अलग थ्रेड में चलती हैं और UI को ब्लॉक नहीं करती हैं। तो, क्या मैं सिर्फ सिंक कॉल के साथ रह सकता हूं?
- उपरोक्त कोड मेरे स्थानीय बॉक्स में चलाया गया था। ठेस स्थापना में, DNS और प्रॉक्सी लुकअप शामिल होंगे। क्या
HttpClient
ओवर का उपयोग करने का कोई फायदा हैWebClient
? - क्या
HttpClient
संगामिति से बेहतर हैWebClient
? परीक्षण के परिणामों से, मुझे लगता है किWebClient
सिंक कॉल बेहतर प्रदर्शन करती हैं। HttpClient
अगर हम .net 4.5 में अपग्रेड करते हैं तो क्या एक बेहतर डिज़ाइन विकल्प होगा? प्रदर्शन प्रमुख डिज़ाइन कारक है।
GetDataFromHttpClientAsync
क्योंकि यह पहले चलता है, अन्य आह्वान का संभावित रूप से काहेड डेटा (स्थानीय मशीन या आपके और गंतव्य के बीच किसी भी पारदर्शी प्रॉक्सी पर होना) का लाभ मिलता है और तेज होगा। इसके अलावा, सही परिस्थितियोंvar response = httpClient.GetAsync("http://localhost:9000/api/values/").Result;
में थ्रेडपूल थ्रेड्स को समाप्त करने के कारण गतिरोध हो सकता है। आपको कभी भी ऐसी गतिविधि पर रोक नहीं लगानी चाहिए जो थ्रेडपूल थ्रेड्स में थ्रेड पूल पर निर्भर करती है, आपकोawait
इसके बजाय इसे थ्रेड को पूल में वापस करना चाहिए ।