Monday, January 13, 2020

Task and async await in C#

While running an application, the application will spawn a thread.  As this thread execution completes the application exits.

private void HelloButton_Click(object sender, EventArgs e)
{
    Thread.Sleep(4000);
    MessageBox.Show("Hello");
}

In this example I causing the thread to sleep for 4 seconds by calling Thread class's Sleep method. Thread class is found within System.Threading namespace.  It is followed by a MessageBox. The UI will freeze till the MessageBox is shown.

It is possible to spawn additional treads by the main thread thread so that time consuming tasks won't freeze the applicaiton.

Task
Task is a specialized  Thread which implements Thread Pool.


private void HelloButton_Click(object sender, EventArgs e)
{
    Task.Run(() =>
    {
    Thread.Sleep(4000);
    MessageBox.Show("Hello");
    });
}

Let's create an application that fetching content from three web sites and display it in a text box.

In the first example I am using WebClient class which follows the synchronous model. As you click the button the window freezes until the fetching of data is complete. This is because the whole application is running in the main thread.

 private void button1_Click(object sender, EventArgs e)
 {
     var sw = Stopwatch.StartNew();
     string data = string.Empty;
     var address = new List<string>
     {
        "https://www.msn.com/en-in",
        "http://ajinspiro.herokuapp.com/",
        "https://www.irctc.co.in/"
      };
      var client = new WebClient();

      foreach (var item in address)
      {
          data += client.DownloadString(item);
      }

      textBox1.Text = data;
      sw.Stop();
      this.Text = sw.ElapsedMilliseconds.ToString();
    }

In the second example we are using HttpClient class which supports asynchronous class. Also we are using async and await.
private async void button1_Click(object sender, EventArgs e)
        {

            var sw = Stopwatch.StartNew();
            string data = string.Empty;
            var address = new List<string>
            {
                "https://www.msn.com/en-in",
                "http://ajinspiro.herokuapp.com/",
                "https://www.irctc.co.in/"
            };
            var client = new HttpClient();
          
            List<Task<HttpResponseMessage>> responseTasks = new List<Task<HttpResponseMessage>>();
            foreach (var url in address)
            {
                Task<HttpResponseMessage> responseTask = client.GetAsync(url);
                responseTasks.Add(responseTask);
            }
            foreach (var responseTask in responseTasks)
            {
                HttpResponseMessage response = await responseTask;
                data = $"{data} {await response.Content.ReadAsStringAsync()}";
            }
            textBox1.Text = data;
            sw.Stop();
            this.Text = sw.ElapsedMilliseconds.ToString();
        }

Task.Run
private async void button2_Click(object sender, EventArgs e)
        {
            var sw = Stopwatch.StartNew();
            string data = string.Empty;
            var address = new List<string>
            {
                "https://www.msn.com/en-in",
                "http://ajinspiro.herokuapp.com/",
                "https://www.irctc.co.in/"
            };
            var client = new HttpClient();

            List<Task<HttpResponseMessage>> responseTasks = new List<Task<HttpResponseMessage>>();
            foreach (var url in address)
            {
                Task<HttpResponseMessage> responseTask = Task.Run(() => client.GetAsync(url));
                responseTasks.Add(responseTask);
            }
            foreach (var responseTask in responseTasks)
            {
                HttpResponseMessage response = await responseTask;
                data = $"{data} {await response.Content.ReadAsStringAsync()}";
            }
            textBox1.Text = data;
            sw.Stop();
            this.Text = sw.ElapsedMilliseconds.ToString();
        }

MVC
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace WebClientMVC.Controllers
{
    public class HomeController : Controller
    {
        

        public ActionResult WebClientEg()
        {
            Stopwatch sw = Stopwatch.StartNew();
            string data = string.Empty;
            List<string> address = new List<string>
            {
                "https://www.msn.com/en-in",
                "http://ajinspiro.herokuapp.com/",
                "https://www.irctc.co.in/"
             };

            using (var client = new WebClient())
            {
                foreach (var item in address)
                {
                    data += client.DownloadString(item);
                }
            }

            sw.Stop();
            ViewBag.Time = sw.ElapsedMilliseconds;
            ViewBag.Data = data;
            return View();
        }

        public async Task<ActionResult> HttpClientAsyncEg()
        {
            Stopwatch sw = Stopwatch.StartNew();
            string data = string.Empty;
            List<string> address = new List<string>
            {
                "https://www.msn.com/en-in",
                "http://ajinspiro.herokuapp.com/",
                "https://www.irctc.co.in/"
             };

            using (var client = new HttpClient())
            {
                foreach (var item in address)
                {
                    var httpResponse = await client.GetAsync(item);
                    data += await httpResponse.Content.ReadAsStringAsync();
                }
            }

            sw.Stop();
            ViewBag.Time = sw.ElapsedMilliseconds;
            ViewBag.Data = data;
            return View();
        }
        public async Task<ActionResult> TaskAsync()
        {
            Stopwatch sw = Stopwatch.StartNew();
            string data = string.Empty;
            List<string> address = new List<string>
            {
                "https://www.msn.com/en-in",
                "http://ajinspiro.herokuapp.com/",
                "https://www.irctc.co.in/"
             };
            List<Task<HttpResponseMessage>> tasks = new List<Task<HttpResponseMessage>>();

            using (var client = new HttpClient())
            {
                foreach (var item in address)
                {
                    tasks.Add(client.GetAsync(item));
                }
                foreach (var task in tasks)
                {
                    var httpResponse = await task;
                    data += await httpResponse.Content.ReadAsStringAsync();
                }
            }

            sw.Stop();
            ViewBag.Time = sw.ElapsedMilliseconds;
            ViewBag.Data = data;
            return View();
        }

No comments:

Post a Comment