এইচটিপিপিলেট এবং ওয়েবক্লিয়েন্টের মধ্যে সিদ্ধান্ত নেওয়া


218

আমাদের ওয়েব অ্যাপ্লিকেশন। নেট ফ্রেমওয়ার্ক 4.0 এ চলছে। ইউআই এজ্যাক্স কলগুলির মাধ্যমে নিয়ন্ত্রণকারী পদ্ধতিগুলিকে কল করে।

আমাদের বিক্রেতার কাছ থেকে আমাদের আরএসটি পরিষেবা গ্রহণ করা দরকার। নেট নেট 4.0.০ এ REST পরিষেবা কল করার সর্বোত্তম উপায়টি আমি মূল্যায়ন করছি। আরআরএসটি পরিষেবাটির জন্য বেসিক অথেনটিকেশন স্কিম প্রয়োজন এবং এটি এক্সএমএল এবং জেএসএন উভয় ক্ষেত্রেই ডেটা ফেরত দিতে পারে। বিশাল ডেটা আপলোড / ডাউনলোড করার প্রয়োজন নেই এবং ভবিষ্যতে আমি কিছুই দেখতে পাচ্ছি না। আমি আরএসটি ব্যবহারের জন্য কয়েকটি ওপেন সোর্স কোড প্রকল্পগুলি দেখেছি এবং প্রকল্পে অতিরিক্ত নির্ভরতা সাব্যস্ত করার জন্য তাদের কোনও মান খুঁজে পাইনি। মূল্যায়ন শুরু WebClientএবং HttpClient। আমি নিউগেট থেকে .NET 4.0 এর জন্য এইচটিপিপিলেটটি ডাউনলোড করেছি।

আমি মধ্যে পার্থক্য অনুসন্ধান WebClientএবং HttpClientএবং এই সাইটের উল্লেখ করেন যে, একক HttpClient সব ব্যবস্থা করতে সক্ষম সমবর্তী কল এবং এটা ডিএনএস, কুকি কনফিগ এবং প্রমাণীকরণ সমাধান পুনরায় ব্যবহার করতে পারেন। আমি এখনও ব্যবহারিক মান দেখতে পেলাম না যা পার্থক্যের কারণে আমরা লাভ করতে পারি।

WebClient(সিঙ্ক কলগুলি), HttpClient(সিঙ্ক এবং অ্যাসিঙ্ক) কীভাবে সম্পাদন করে তা খুঁজে পেতে আমি একটি দ্রুত পারফরম্যান্স পরীক্ষা করেছি । এবং ফলাফল এখানে:

HttpClientসমস্ত অনুরোধের জন্য একই উদাহরণ ব্যবহার করে (সর্বনিম্ন - সর্বোচ্চ)

ওয়েবক্লিয়েন্ট সিঙ্ক: 8 এমএস - 167
এমএসএস এইচটিপিপ্লিনেন্ট সিঙ্ক: 3 এমএস - 7228
এমএসএস এইচটিটিপি ক্লায়েন্ট অ্যাসিঙ্ক: 985 - 10405 এমএস

HttpClientপ্রতিটি অনুরোধের জন্য একটি নতুন ব্যবহার (মিনিট - সর্বাধিক)

ওয়েবক্লিয়েন্ট সিঙ্ক: 4 এমএস - 297
এমএসএস এইচটিপিপ্লিনেন্ট সিঙ্ক: 3 এমএস - 7953
এমএসএস এইচটিপিপ্লাইয়েন্ট অ্যাসিঙ্ক: 1027 - 10834 এমএস

কোড

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);
        }
    }
}

আমার প্রশ্নগুলো

  1. আরআরএসটি কলগুলি 3-4- তে ফিরে আসে যা গ্রহণযোগ্য। আরএসএসটি পরিষেবার জন্য কলগুলি নিয়ামক পদ্ধতিতে শুরু করা হয় যা এজ্যাক্স কল থেকে শুরু হয়। শুরুতে, কলগুলি আলাদা থ্রেডে চলে এবং ইউআইকে অবরুদ্ধ করে না। সুতরাং, আমি কি কেবল সিঙ্ক কলগুলি দিয়ে আটকাতে পারি?
  2. উপরের কোডটি আমার লোকালবক্সে চালিত হয়েছিল। প্রোড সেটআপে, ডিএনএস এবং প্রক্সি লুকআপ জড়িত থাকবে। HttpClientওভার ব্যবহারের কোনও সুবিধা আছে WebClient?
  3. HttpClientসম্মতি কি এর চেয়ে ভাল WebClient? পরীক্ষার ফলাফল থেকে, আমি WebClientসিঙ্ক কলগুলি আরও ভাল সম্পাদন করতে দেখছি ।
  4. হবে HttpClientআরো ভালো নকশা পছন্দ যদি আমরা নেট 4.5 এ আপগ্রেড হবে? পারফরম্যান্স মূল নকশা ফ্যাক্টর।

5
আপনার পরীক্ষাটি GetDataFromHttpClientAsyncএটি প্রথমে চালিত হওয়ার পক্ষে অন্যায় , অন্য আহ্বানগুলি সম্ভাব্যভাবে ক্যাশেড ডেটা (স্থানীয় মেশিনে বা আপনার এবং গন্তব্যের মধ্যে কোনও স্বচ্ছ প্রক্সিতে থাকায়) লাভ করে এবং এটি আরও দ্রুত হবে। এছাড়াও, সঠিক অবস্থার অধীনে var response = httpClient.GetAsync("http://localhost:9000/api/values/").Result;থ্রেডপুলের থ্রেডগুলি ক্লান্ত করার কারণে আপনার অচলাবস্থার সৃষ্টি হতে পারে। থ্রেডপুল থ্রেডগুলিতে থ্রেড পুলের উপর নির্ভর করে এমন কোনও ক্রিয়াকলাপ আপনার কখনও আটকানো উচিত নয়, awaitপরিবর্তে এটি থ্রেডটি পুলটিতে ফিরিয়ে দেয় should
স্কট চেম্বারলাইন 21

1
ওয়েব এপিআই ক্লায়েন্টের সাথে এইচটিপিপি্লিয়েন্ট জেএসএন / এক্সএমএল রিস্ট ক্লায়েন্টের জন্য দুর্দান্ত।
Cory নেলসন

@ স্কট চেম্বারলাইন - আপনার উত্তরের জন্য ধন্যবাদ। সমস্ত টেস্ট কল সমান্তরাল হিসাবে চালিত। ফোরাইচ, কোনটি আগে চালিত হত তার কোন গ্যারান্টি নেই। এছাড়াও, পরিষেবাটিতে প্রথম কলটি ছিল getDataFromHttpClientAsync থেকে, getDataFromHttpClientAsync এর পরবর্তী সমস্ত কলগুলি ক্যাশে থেকে উপকার পাওয়া উচিত ছিল এবং দ্রুত চালানো উচিত। রেজাল্টে আমি তা দেখিনি। আরজিডি অপেক্ষা করুন, আমরা এখনও ৪.০ ব্যবহার করছি। আমি আপনার সাথে সম্মত হই যে সিঙ্ক ফ্যাশনে এইচটিপিপ্লিয়েন্টটি অচলাবস্থার দিকে পরিচালিত করবে এবং আমি আমার নকশার বিবেচনার বাইরে এই বিকল্পটিকে রায় দিচ্ছি।
ব্যবহারকারী 3092913

@ কৌরিয়েলসন আপনি কী দয়া করে ওয়েব এপিআই ক্লায়েন্টের সাথে এইচটিপিপ্লিনেন্ট কোনও জেএসএন / এক্সএমএল আরএসইটি ক্লায়েন্টের জন্য দুর্দান্ত?
ব্যবহারকারীর 3092913

2
এইচটিপিপিলেট এবং ওয়েবক্লিনেন্টের মধ্যে পার্থক্য সম্পর্কে এখানে কয়েকটি শব্দ দেওয়া আছে: ব্লগস.এমএসএনএন
বি /

উত্তর:


243

আমি উভয় এফ # এবং ওয়েব এপিআই ওয়ার্ল্ডে বাস করি।

ওয়েব এপিআই এর সাথে প্রচুর পরিমাণে ভাল জিনিস ঘটছে, বিশেষত সুরক্ষার জন্য বার্তা হ্যান্ডলারগুলির আকারে ইত্যাদি

আমি জানি আমার একটাই মতামত, তবে আমি কেবল HttpClientভবিষ্যতের কোনও কাজের জন্য ব্যবহারের পরামর্শ দেব । সম্ভবত সেই সমাবেশটি System.Net.Httpসরাসরি ব্যবহার না করেই বেরিয়ে আসা অন্যান্য টুকরোগুলির কিছুটা লাভ করার কিছু উপায় আছে তবে আমি কীভাবে ভাবতে পারি না যে এটি এই সময়ে কীভাবে কার্যকর হবে।

এই দুটি তুলনা কথা বলছি

  • এইচটিপিপ্লেইন্ট ওয়েবক্লিয়েন্টের চেয়ে এইচটিটিপি-র আরও বেশি কাছাকাছি।
  • এইচটিপিপ্লিয়েন্টটি ওয়েব ক্লায়েন্টের সম্পূর্ণ প্রতিস্থাপন বলে বোঝানো হয়নি, যেহেতু রিপোর্টের অগ্রগতি, কাস্টম ইউআরআই স্কিম এবং ওয়েবক্লিয়েন্ট সরবরাহ করে এমন এফটিপি কল করার মতো জিনিস রয়েছে - তবে এইচটিটিপি ক্লিনেন্ট তা দেয় না।
+--------------------------------------------+--------------------------------------------+
|               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                |
+--------------------------------------------+--------------------------------------------+

আপনি যদি নেট .৪.৪ ব্যবহার করছেন তবে দয়া করে মাইক্রোসফ্ট বিকাশকারীদের জন্য সরবরাহ করে এমন এইচটিপিপ্লিনেন্টের সাথে অ্যাসিঙ্ক সদ্ব্যবহার ব্যবহার করুন। এইচটিটিপি-র সার্ভার সাইড ভাইদের যারা এইচটিটিপিক্রাইয়েস্ট এবং এইচটিটিপিআরেস্পোনস, তাদের কাছে এইচটিটিপিসিলেট খুব সমান্তরাল।

আপডেট: নতুন এইচটিটিপিপ্লায়েন্ট এপিআই ব্যবহার করার জন্য 5 টি কারণ:

  • শক্তভাবে টাইপ করা শিরোনাম।
  • ভাগ করা ক্যাশে, কুকিজ এবং শংসাপত্রগুলি
  • কুকি এবং ভাগ করা কুকিজ অ্যাক্সেস
  • ক্যাচিং এবং ভাগ করা ক্যাশে নিয়ন্ত্রণ করুন।
  • আপনার কোড মডিউলটি ASP.NET পাইপলাইনে ইনজেক্ট করুন। ক্লিনার এবং মডিউলার কোড।

উল্লেখ

সি # 5.0 জোসেফ আলবাহারি

(চ্যানেল 9 - ভিডিও বিল্ড 2013)

ওয়েব পরিষেবাদিগুলিতে সংযুক্ত হওয়ার জন্য নতুন এইচটিটিপিপ্লিনেন্ট এপিআই ব্যবহার করার পাঁচটি দুর্দান্ত কারণ

ওয়েবক্লিয়েন্ট বনাম এইচটিটিপিপ্লাইট বনাম এইচটিটিপিওয়েব্রেকয়েস্ট


4
এটি উল্লেখ করা উচিত যে এইচটিপিপ্লেইন্টটি নেট নেট for.০ এর জন্যও উপলব্ধ
টড মেনিয়ার

2
এইচটিপিপ্লিনেন্টের তুলনায় ওয়েবক্লিয়েন্ট কেন তীব্রতর বলে মনে হচ্ছে তা ব্যাখ্যা করে না। এছাড়াও WebClientএখন অসম্পূর্ণ পদ্ধতি রয়েছে বলে মনে হয়।
ক্রাশ

8
@ ক্রাশ কারণ এটি ওপি প্রতিটি একক অনুরোধের জন্য এইচটিপিপিপ্লায়েন্টের একটি নতুন উদাহরণ তৈরি করছে। পরিবর্তে আপনার নিজের আবেদনের সময়কালের জন্য HTTPClient এর একক উদাহরণ ব্যবহার করা উচিত। স্ট্যাকওভারফ্লো.com
গ্যাব্রিয়েল

6
এটা লক্ষণীয় মূল্য WebClientপাওয়া যায় না .Net Coreতবে HttpClientহয়।
প্রণব সিং

3
যেহেতু। নেট কোর ২.০ ওয়েবক্লিয়েন্ট (হাজার হাজার অন্যান্য এপিআইয়ের মধ্যে) ফিরে এসেছে এবং উপলভ্য।
কোডারবাং

56

এইচটিপিসিলেট হ'ল এপিআইয়ের নতুন এবং এতে এর সুবিধা রয়েছে

  • একটি অ্যাসিঙ্ক প্রোগ্রামিং মডেল আছে
  • হেনরিক এফ নীলসনের মাধ্যমে কাজ করা যিনি মূলত এইচটিটিপির অন্যতম উদ্ভাবক, এবং তিনি এপিআই ডিজাইন করেছিলেন যাতে আপনার পক্ষে এইচটিটিপি স্ট্যান্ডার্ড অনুসরণ করা সহজ হয়, উদাহরণস্বরূপ, মান-অনুমানের শিরোনাম উত্পন্ন করা
  • নেট ফ্রেমওয়ার্ক 4.5 এ রয়েছে, সুতরাং এটির ভবিষ্যতের জন্য কিছু গ্যারান্টিযুক্ত স্তরের সমর্থন রয়েছে support
  • আপনি যদি অন্য প্ল্যাটফর্মগুলিতে -। নেট ,.০, উইন্ডোজ ফোন ইত্যাদি ব্যবহার করতে চান তবে গ্রন্থাগারের xcopyable / পোর্টেবল-ফ্রেমওয়ার্ক সংস্করণ রয়েছে

আপনি যদি এমন কোনও ওয়েব সার্ভিস লিখছেন যা অন্য ওয়েব পরিষেবাদিগুলিতে আরআরটি কল করে, আপনি আপনার সমস্ত আরএসটি কলের জন্য একটি অ্যাসিঙ্ক প্রোগ্রামিং মডেলটি ব্যবহার করা উচিত, যাতে আপনি থ্রেড অনাহারে না পড়ে। আপনি সম্ভবত নতুন সি # সংকলকটিও ব্যবহার করতে চান যার অসিঙ্ক / সাপোর্টের প্রতীক্ষা রয়েছে।

দ্রষ্টব্য: এটি আরও অভিনেতা AFAIK নয়। আপনি যদি একটি সুষ্ঠু পরীক্ষা তৈরি করেন তবে এটি সম্ভবত কিছুটা অনুরূপ পারফরম্যান্ট।


প্রক্সি স্যুইচ করার কোনও উপায় থাকলে এটি উন্মাদ হবে
এডি 22

3

প্রথমত, আমি বিশেষত ওয়েবক্লিয়েন্ট বনাম এইচটিটিপিকলেন্টের কোনও কর্তৃপক্ষ নই। দ্বিতীয়ত, উপরের আপনার মন্তব্যগুলি থেকে, মনে হয় যে ওয়েবক্লিয়েন্টটি কেবলমাত্র সিঙ্ক হয় যেখানে এইচটিপিপ্লিয়েন্ট উভয়ই।

ওয়েবক্লিয়েন্ট (সিঙ্ক কলগুলি), এইচটিপিপ্লিয়েন্ট (সিঙ্ক এবং অ্যাসিঙ্ক) কীভাবে সম্পাদন করে তা অনুসন্ধান করার জন্য আমি দ্রুত পারফরম্যান্স পরীক্ষা করেছি। এবং ফলাফল এখানে।

আমি দেখতে পাচ্ছি যে ভবিষ্যতের জন্য চিন্তাভাবনা করার সময় একটি বিশাল পার্থক্য হিসাবে, যেমন দীর্ঘ চলমান প্রক্রিয়াগুলি, প্রতিক্রিয়াশীল জিইউআই ইত্যাদি framework


4
WebClientসর্বশেষ .NET সংস্করণগুলিতে অ্যাসিঙ্ক ক্ষমতা রয়েছে বলে মনে হয়। আমি কেন এটি এত বড় স্কেলে এইচটিপিপ্লেইয়েন্টকে ছাড়িয়ে যাচ্ছে বলে মনে হচ্ছে তা জানতে চাই।
ক্রাশ করুন

1
স্ট্যাকওভারফ্লো.com / a / 4988325 / 1662973 অনুসারে , এটি একইরকম বলে মনে হচ্ছে, অন্যটি একে অপরের বিমূর্ততা। হতে পারে, এটি কীভাবে অবজেক্টগুলি ব্যবহৃত / লোড হয় তার উপর নির্ভর করে। সর্বনিম্ন সময়টি এই বিবৃতিটিকে সমর্থন করে যে ওয়েবক্লিয়েন্ট আসলে এইচটিপিপ্লিয়েন্টের বিমূর্ততা, সুতরাং ওভারহেডের এক মিলিসেকেন্ডের মূল্য রয়েছে। এটি কীভাবে ওয়েবক্লিয়েন্টের পুলিং বা ডিসপোজিং করছে তা ফ্রেমওয়ার্কটি "স্নিগ্ধ" হতে পারে।
অ্যান্থনি হর্নে

3

HttpClientFactory

আপনি এইচটিপিপ্লেইন্ট তৈরি করতে পারেন এমন বিভিন্ন উপায়ে মূল্যায়ন করা গুরুত্বপূর্ণ এবং এর একটি অংশ এইচটিপিপিপ্লায়েন্টফ্যাক্টরি বোঝা যাচ্ছে।

https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests

এটি আমার জানা সরাসরি উত্তর নয় - তবে আপনি যে কোনও new HttpClient(...)জায়গায় এসে শেষ না করেই এখানে শুরু করা ভাল ।


2

আমার এইচটিপিপি্লিয়েন্ট, ওয়েবক্লিয়েন্ট, এইচটিটিপিওব্রেসপন্সের মধ্যে বেঞ্চমার্ক রয়েছে তারপরে রেস্ট ওয়েব এপি কল করুন

এবং ফলাফল কল বিশ্রাম ওয়েব অপি বেঞ্চমার্ক

--------------------- মঞ্চ 1 ---- 10 অনুরোধ

{00: 00: 17.2232544} ====> এইচটিটিপি ক্লিনেট

{00: 00: 04.3108986} ====> ওয়েব রিকোয়েস্ট

{00: 00: 04.5436889} ====> ওয়েবক্লিয়েন্ট

--------------------- মঞ্চ 1 ---- 10 অনুরোধ - ছোট আকার

{00: 00: 17,2232544} ====> HttpClinet

{00: 00: 04,3108986} ====> WebRequest

{00: 00: 04,5436889} ====> WebClient

--------------------- পর্যায় 3 ---- 10 সিঙ্কের অনুরোধ - ছোট আকার

{00: 00: 15,3047502} ====> HttpClinet

{00: 00: 03,5505249} ====> WebRequest

{00: 00: 04,0761359} ====> WebClient

--------------------- পর্যায় 4 ---- 100 সিঙ্ক অনুরোধ - ছোট আকার

{00: 03: 23,6268086} ====> HttpClinet

{00: 00: 47,1406632} ====> WebRequest

{00: 01: 01,2319499} ====> WebClient

--------------------- পর্যায় 5 ---- 10 সিঙ্কের অনুরোধ - সর্বোচ্চ আকার

{00: 00: 58,1804677} ====> HttpClinet

{00: 00: 58,0710444} ====> WebRequest

{00: 00: 38,4170938} ====> WebClient

--------------------- পর্যায় 6 ---- 10 সিঙ্কের অনুরোধ - সর্বাধিক আকার

{00: 01: 04,9964278} ====> HttpClinet

{00: 00: 59,1429764} ====> WebRequest

{00: 00: 32,0584836} ====> WebClient

_____ ওয়েবক্লিয়েন্ট দ্রুত ()

var stopWatch = new Stopwatch();
        stopWatch.Start();
        for (var i = 0; i < 10; ++i)
        {
            CallGetHttpClient();
            CallPostHttpClient();
        }

        stopWatch.Stop();

        var httpClientValue = stopWatch.Elapsed;

        stopWatch = new Stopwatch();

        stopWatch.Start();
        for (var i = 0; i < 10; ++i)
        {
            CallGetWebRequest();
            CallPostWebRequest();
        }

        stopWatch.Stop();

        var webRequesttValue = stopWatch.Elapsed;


        stopWatch = new Stopwatch();

        stopWatch.Start();
        for (var i = 0; i < 10; ++i)
        {

            CallGetWebClient();
            CallPostWebClient();

        }

        stopWatch.Stop();

        var webClientValue = stopWatch.Elapsed;

// ------------------------- কার্যাবলী

private void CallPostHttpClient()
    {
        var httpClient = new HttpClient();
        httpClient.BaseAddress = new Uri("https://localhost:44354/api/test/");
        var responseTask = httpClient.PostAsync("PostJson", null);
        responseTask.Wait();

        var result = responseTask.Result;
        var readTask = result.Content.ReadAsStringAsync().Result;

    }
    private void CallGetHttpClient()
    {
        var httpClient = new HttpClient();
        httpClient.BaseAddress = new Uri("https://localhost:44354/api/test/");
        var responseTask = httpClient.GetAsync("getjson");
        responseTask.Wait();

        var result = responseTask.Result;
        var readTask = result.Content.ReadAsStringAsync().Result;

    }
    private string CallGetWebRequest()
    {
        var request = (HttpWebRequest)WebRequest.Create("https://localhost:44354/api/test/getjson");

        request.Method = "GET";
        request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;

        var content = string.Empty;

        using (var response = (HttpWebResponse)request.GetResponse())
        {
            using (var stream = response.GetResponseStream())
            {
                using (var sr = new StreamReader(stream))
                {
                    content = sr.ReadToEnd();
                }
            }
        }

        return content;
    }
    private string CallPostWebRequest()
    {

        var apiUrl = "https://localhost:44354/api/test/PostJson";


        HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(new Uri(apiUrl));
        httpRequest.ContentType = "application/json";
        httpRequest.Method = "POST";
        httpRequest.ContentLength = 0;

        using (var httpResponse = (HttpWebResponse)httpRequest.GetResponse())
        {
            using (Stream stream = httpResponse.GetResponseStream())
            {
                var json = new StreamReader(stream).ReadToEnd();
                return json;
            }
        }

        return "";
    }

    private string CallGetWebClient()
    {
        string apiUrl = "https://localhost:44354/api/test/getjson";


        var client = new WebClient();

        client.Headers["Content-type"] = "application/json";

        client.Encoding = Encoding.UTF8;

        var json = client.DownloadString(apiUrl);


        return json;
    }

    private string CallPostWebClient()
    {
        string apiUrl = "https://localhost:44354/api/test/PostJson";


        var client = new WebClient();

        client.Headers["Content-type"] = "application/json";

        client.Encoding = Encoding.UTF8;

        var json = client.UploadString(apiUrl, "");


        return json;
    }

1
উপরে গ্যাব্রিয়েল এর মন্তব্য দেখুন। সংক্ষেপে, আপনি যদি এইচটিটিপিপ্লিনেন্টের একটি উদাহরণ তৈরি করেন এবং এটি পুনরায় ব্যবহার করেন তবে এইচটিপিপি্লিয়েন্টটি আরও দ্রুত।
এলটি ড্যান

1

সম্ভবত আপনি সমস্যাটি অন্যরকমভাবে ভাবতে পারেন। WebClientএবং HttpClientমূলত একই জিনিসটির বিভিন্ন বাস্তবায়ন। আমি যা প্রস্তাব করি তা হ'ল আপনার অ্যাপ্লিকেশন জুড়ে আইওসি কনটেইনার দিয়ে নির্ভরতা ইঞ্জেকশন প্যাটার্নটি প্রয়োগ করা। নিম্ন স্তরের এইচটিটিপি স্থানান্তরের চেয়ে উচ্চ স্তরের বিমূর্ততার সাথে আপনার ক্লায়েন্ট ইন্টারফেস তৈরি করা উচিত। আপনি কংক্রিট শ্রেণীর ব্যবহার লিখতে পারেন উভয় এবংWebClientHttpClient এবং তারপরে কনফিগার মাধ্যমে প্রয়োগটি ইনজেক্ট করতে IoC ধারকটি ব্যবহার করতে পারেন।

এটি আপনাকে যা করতে দেয় তা হ'ল এটির মধ্যে HttpClientএবং WebClientসহজেই স্যুইচ করা যাতে আপনি উত্পাদন পরিবেশে উদ্দেশ্যমূলকভাবে পরীক্ষা করতে সক্ষম হন।

সুতরাং প্রশ্ন যেমন:

আমরা। নেট ৪.৫ এ আপগ্রেড করা হলে এইচটিপিপিলেয়েন্ট কী আরও ভাল ডিজাইনের পছন্দ হতে পারে?

IoC ধারক ব্যবহার করে দুটি ক্লায়েন্ট বাস্তবায়নের মধ্যে স্যুইচিংয়ের মাধ্যমে বস্তুনিষ্ঠভাবে উত্তর দেওয়া যেতে পারে। এখানে একটি উদাহরণ ইন্টারফেস যা আপনি নির্ভর করতে পারেন যা সম্পর্কে HttpClientবা কোনও বিবরণ অন্তর্ভুক্ত করে না WebClient

/// <summary>
/// Dependency Injection abstraction for rest clients. 
/// </summary>
public interface IClient
{
    /// <summary>
    /// Adapter for serialization/deserialization of http body data
    /// </summary>
    ISerializationAdapter SerializationAdapter { get; }

    /// <summary>
    /// Sends a strongly typed request to the server and waits for a strongly typed response
    /// </summary>
    /// <typeparam name="TResponseBody">The expected type of the response body</typeparam>
    /// <typeparam name="TRequestBody">The type of the request body if specified</typeparam>
    /// <param name="request">The request that will be translated to a http request</param>
    /// <returns></returns>
    Task<Response<TResponseBody>> SendAsync<TResponseBody, TRequestBody>(Request<TRequestBody> request);

    /// <summary>
    /// Default headers to be sent with http requests
    /// </summary>
    IHeadersCollection DefaultRequestHeaders { get; }

    /// <summary>
    /// Default timeout for http requests
    /// </summary>
    TimeSpan Timeout { get; set; }

    /// <summary>
    /// Base Uri for the client. Any resources specified on requests will be relative to this.
    /// </summary>
    Uri BaseUri { get; set; }

    /// <summary>
    /// Name of the client
    /// </summary>
    string Name { get; }
}

public class Request<TRequestBody>
{
    #region Public Properties
    public IHeadersCollection Headers { get; }
    public Uri Resource { get; set; }
    public HttpRequestMethod HttpRequestMethod { get; set; }
    public TRequestBody Body { get; set; }
    public CancellationToken CancellationToken { get; set; }
    public string CustomHttpRequestMethod { get; set; }
    #endregion

    public Request(Uri resource,
        TRequestBody body,
        IHeadersCollection headers,
        HttpRequestMethod httpRequestMethod,
        IClient client,
        CancellationToken cancellationToken)
    {
        Body = body;
        Headers = headers;
        Resource = resource;
        HttpRequestMethod = httpRequestMethod;
        CancellationToken = cancellationToken;

        if (Headers == null) Headers = new RequestHeadersCollection();

        var defaultRequestHeaders = client?.DefaultRequestHeaders;
        if (defaultRequestHeaders == null) return;

        foreach (var kvp in defaultRequestHeaders)
        {
            Headers.Add(kvp);
        }
    }
}

public abstract class Response<TResponseBody> : Response
{
    #region Public Properties
    public virtual TResponseBody Body { get; }

    #endregion

    #region Constructors
    /// <summary>
    /// Only used for mocking or other inheritance
    /// </summary>
    protected Response() : base()
    {
    }

    protected Response(
    IHeadersCollection headersCollection,
    int statusCode,
    HttpRequestMethod httpRequestMethod,
    byte[] responseData,
    TResponseBody body,
    Uri requestUri
    ) : base(
        headersCollection,
        statusCode,
        httpRequestMethod,
        responseData,
        requestUri)
    {
        Body = body;
    }

    public static implicit operator TResponseBody(Response<TResponseBody> readResult)
    {
        return readResult.Body;
    }
    #endregion
}

public abstract class Response
{
    #region Fields
    private readonly byte[] _responseData;
    #endregion

    #region Public Properties
    public virtual int StatusCode { get; }
    public virtual IHeadersCollection Headers { get; }
    public virtual HttpRequestMethod HttpRequestMethod { get; }
    public abstract bool IsSuccess { get; }
    public virtual Uri RequestUri { get; }
    #endregion

    #region Constructor
    /// <summary>
    /// Only used for mocking or other inheritance
    /// </summary>
    protected Response()
    {
    }

    protected Response
    (
    IHeadersCollection headersCollection,
    int statusCode,
    HttpRequestMethod httpRequestMethod,
    byte[] responseData,
    Uri requestUri
    )
    {
        StatusCode = statusCode;
        Headers = headersCollection;
        HttpRequestMethod = httpRequestMethod;
        RequestUri = requestUri;
        _responseData = responseData;
    }
    #endregion

    #region Public Methods
    public virtual byte[] GetResponseData()
    {
        return _responseData;
    }
    #endregion
}

সম্পূর্ণ কোড

HttpClient বাস্তবায়ন

তুমি ব্যবহার করতে পার Task.RunWebClientএটির প্রয়োগে আপনি অ্যাসিক্রোনালিকভাবে রান তৈরি ।

নির্ভরতা ইনজেকশন, যখন ভালভাবে সম্পন্ন করা হয় তখন নিম্ন স্তরের সিদ্ধান্তগুলি সামনে রাখার সমস্যা কমাতে সহায়তা করে। শেষ পর্যন্ত, আসল উত্তরটি জানার একমাত্র উপায় হ'ল লাইভ পরিবেশে উভয়ই চেষ্টা করে দেখুন এবং কোনটি সবচেয়ে ভাল কাজ করে তা দেখুন। এটি বেশ সম্ভাব্য যা WebClientকিছু গ্রাহকের HttpClientপক্ষে আরও ভাল কাজ করতে পারে এবং অন্যের জন্য আরও ভাল কাজ করতে পারে। এ কারণেই বিমূর্ততা গুরুত্বপূর্ণ। এর অর্থ হল অ্যাপটির মৌলিক নকশাটি পরিবর্তন না করেই কোডটি দ্রুত সরিয়ে নেওয়া বা কনফিগারেশনের মাধ্যমে পরিবর্তন করা যেতে পারে।


1

2020 সাল থেকে অপ্রিয় জনমত:

এটি যখন এএসপি.নেট অ্যাপ্লিকেশন আসে তখন আমি WebClientতার চেয়ে বেশি পছন্দ করি HttpClientকারণ:

  1. আধুনিক বাস্তবায়ন আস্ক / প্রতীক্ষিত টাস্ক-ভিত্তিক পদ্ধতি নিয়ে আসে
  2. ছোট মেমরির পদচিহ্ন এবং 2x-5x দ্রুত রয়েছে (অন্যান্য উত্তর ইতিমধ্যে এটি উল্লেখ করেছে) বিশেষত পরিস্থিতিতে যখন আপনি কেবল " আপনার অ্যাপ্লিকেশনটির জন্য এইচটিপিপ্লিয়েন্টের একক উদাহরণ পুনরায় ব্যবহার করতে পারবেন না " যেমন অন্যান্য মন্তব্যকারীদের পরামর্শ দেয়। এবং এএসপি.এনইটি হ'ল সেই দৃশ্যের মধ্যে একটি - কোনও "আবেদনের আজীবন" নেই, কেবলমাত্র একটি অনুরোধের আজীবন।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.