简体   繁体   中英

HttpClient GetAsync taking ~2 seconds

My wpf program reads commands from a text file, and then sends those commands out over HttpClient. Each GetAsync response takes about 2 seconds to complete. This seems excessively long, especially when I have 50 commands to send.

Is this a normal amount of time for HttpClient to send/receive a GetAsync Message? Is there a faster way to do this?

static readonly HttpClient client = new HttpClient();
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void Register_ClickAsync(object sender, RoutedEventArgs e)
        {

            int counter = 0;
            string line;

            System.IO.StreamReader file = new System.IO.StreamReader(@"C\path.txt");

            while ((line = file.ReadLine()) != null)
            {
                try
                {
                    var watch = Stopwatch.StartNew();
                    HttpResponseMessage response = await client.GetAsync(line);
                    response.EnsureSuccessStatusCode();
                    string responseBody = await response.Content.ReadAsStringAsync();

                    watch.Stop();
                    var elapsedMS = watch.ElapsedMilliseconds;
                    RequestTextBox.Text += "\n" + elapsedMS;

                }
                catch (HttpRequestException ex)
                {
                    Console.WriteLine("\nException Caught!");
                    Console.WriteLine("Message :{0} ", ex.Message);
                    this.RequestTextBox.Text += ("\n" + "Message: {0} ", ex.Message);
                }
            }
            file.Close();  
        }
    }

UPDATE: This original program is a .net Core WPF app. I created a .net framework WPF app with the exact same code. The .net framework app takes 2000 ms to send the first HttpClient GetAsync command, and then <10 ms for subsequent commands. This is a massive performance increase. Does anyone have an explanation? I have been unable to find any articles explaining this.

Your code is awaiting for each request.

You can create many tasks by calling GetAsync and then wait them all with Task.WhenAll() . It will be more faster.

You are not using the async paradigm correctly. You are awaiting an async call immediately, and as a result it acts the same as a synchronous method. The idea of an async method is that it starts work and runs in the background, while not blocking other threads from executing. This allows you to run many threads at once and then return them when you are ready to use them. I would highly recommend the msft docs in this case. They use the example of making breakfast, in this example they are doing it incorrectly, as you are in your question:

Coffee cup = PourCoffee();
Console.WriteLine("coffee is ready");
Task<Egg> eggsTask = FryEggs(2);
Egg eggs = await eggsTask;
Console.WriteLine("eggs are ready");
Task<Bacon> baconTask = FryBacon(3);
Bacon bacon = await baconTask;
Console.WriteLine("bacon is ready");
Task<Toast> toastTask = ToastBread(2);
Toast toast = await toastTask;
ApplyButter(toast);
ApplyJam(toast);
Console.WriteLine("toast is ready");
Juice oj = PourOJ();
Console.WriteLine("oj is ready");

Console.WriteLine("Breakfast is ready!");

To fix it you must call Task.WhenAny() or Task.WhenAll(). This allows you to run all of the tasks at once and return them after they have finished (or as they finish). This will greatly improve your performance.

static async Task Main(string[] args)
{
    Coffee cup = PourCoffee();
    Console.WriteLine("coffee is ready");
    var eggsTask = FryEggsAsync(2);
    var baconTask = FryBaconAsync(3);
    var toastTask = MakeToastWithButterAndJamAsync(2);

    var allTasks = new List<Task>{eggsTask, baconTask, toastTask};
    while (allTasks.Any())
    {
        Task finished = await Task.WhenAny(allTasks);
        if (finished == eggsTask)
        {
            Console.WriteLine("eggs are ready");
        }
        else if (finished == baconTask)
        {
            Console.WriteLine("bacon is ready");
        }
        else if (finished == toastTask)
        {
            Console.WriteLine("toast is ready");
        }
        allTasks.Remove(finished);
    }
    Juice oj = PourOJ();
    Console.WriteLine("oj is ready");
    Console.WriteLine("Breakfast is ready!");

    async Task<Toast> MakeToastWithButterAndJamAsync(int number)
    {
        var toast = await ToastBreadAsync(number);
        ApplyButter(toast);
        ApplyJam(toast);
        return toast;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM