เว็บแอปของเรากำลังทำงานใน. Net Framework 4.0 UI เรียกวิธีควบคุมผ่านการเรียก ajax
เราจำเป็นต้องใช้บริการ REST จากผู้ขายของเรา ฉันกำลังประเมินวิธีที่ดีที่สุดในการเรียกใช้บริการ REST ใน. Net 4.0 เซอร์วิส REST ต้องการ Basic Authentication Scheme และสามารถส่งคืนข้อมูลทั้งใน XML และ JSON ไม่มีข้อกำหนดสำหรับการอัปโหลด / ดาวน์โหลดข้อมูลขนาดใหญ่และฉันไม่เห็นอะไรเลยในอนาคต ฉันดูโครงการโอเพนซอร์สสองสามโครงการสำหรับการใช้ REST และไม่พบค่าใด ๆ ในการพิสูจน์การพึ่งพาเพิ่มเติมในโครงการ เริ่มต้นในการประเมินและWebClient
HttpClient
ฉันดาวน์โหลด HttpClient สำหรับ. Net 4.0 จาก NuGet
ผมค้นหาความแตกต่างระหว่างWebClient
และHttpClient
และเว็บไซต์นี้บอกว่าเดียว HttpClient สามารถจัดการกับสายพร้อมกันและสามารถใช้การแก้ไข DNS, การตั้งค่าคุกกี้และการตรวจสอบ ฉันยังไม่เห็นค่าจริงที่เราอาจได้รับเนื่องจากความแตกต่าง
ฉันทำการทดสอบประสิทธิภาพอย่างรวดเร็วเพื่อค้นหาว่าWebClient
(การเรียกสาย), HttpClient
(ซิงค์และ async) ทำงานอย่างไร และนี่คือผลลัพธ์:
ใช้HttpClient
อินสแตนซ์เดียวกันสำหรับคำขอทั้งหมด (ขั้นต่ำ - สูงสุด)
การซิงค์ WebClient: 8 ms - 167 ms
ซิงค์ HttpClient: 3 ms - 7228 ms
astt HttpClient: 985 - 10405 ms
ใช้ใหม่HttpClient
สำหรับแต่ละคำขอ (ต่ำสุด - สูงสุด)
การซิงค์ WebClient: 4 ms - 297 ms
ซิงค์ HttpClient: 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);
}
}
}
คำถามของฉัน
- การเรียกส่วนที่เหลือส่งคืนใน 3-4s ซึ่งเป็นที่ยอมรับ เซอร์วิส Call to REST เริ่มต้นในวิธีการควบคุมซึ่งเรียกใช้จากการโทร ajax ในการเริ่มต้นการโทรจะทำงานในเธรดอื่นและไม่บล็อก UI ดังนั้นฉันสามารถเพียงแค่ติดกับสายซิงค์?
- รหัสข้างต้นถูกเรียกใช้ในกล่องภายในเครื่องของฉัน ในการตั้งค่าผลิตภัณฑ์จะทำการค้นหา DNS และพร็อกซี มีข้อได้เปรียบในการใช้งานหรือไม่
HttpClient
มากกว่าWebClient
? - การทำงาน
HttpClient
พร้อมกันดีกว่าWebClient
หรือไม่ จากผลการทดสอบฉันเห็นว่าการWebClient
ซิงค์มีประสิทธิภาพดีกว่า - จะ
HttpClient
เป็นตัวเลือกการออกแบบที่ดีกว่าถ้าเราอัพเกรดเป็น. Net 4.5 ประสิทธิภาพเป็นปัจจัยสำคัญในการออกแบบ
GetDataFromHttpClientAsync
เนื่องจากการดำเนินการครั้งแรกการเรียกใช้อื่น ๆ จะได้รับประโยชน์จากข้อมูลที่อาจเกิดขึ้น (ไม่ว่าจะเป็นบนเครื่องโลคัลหรือพร็อกซีที่โปร่งใสระหว่างคุณกับปลายทาง) และจะเร็วขึ้น นอกจากนี้ภายใต้เงื่อนไขที่ถูกต้องvar response = httpClient.GetAsync("http://localhost:9000/api/values/").Result;
อาจส่งผลให้เกิดการหยุดชะงักเนื่องจากเธรดเธรดพูลของคุณหมดลง คุณไม่ควรบล็อกกิจกรรมที่ขึ้นอยู่กับเธรดพูลในเธรด ThreadPool คุณควรawait
กลับไปที่เธรดกลับไปที่พูลแทน