Thursday, 25 July 2013

Asynchronous Programming - C# Various way to run a Program in Asynchronous Mode



Asynchronous

In C# There are various way to run a program in Asynchronous way .
What is meant by Asynchronous ?
     Do a work in the background thread , instead of main thread is known as Asynchronous.For a Long running task normally developers do it asynchronous to avoid the UI from non-responsiveness.At the same time we can run the Main thread and do some work in main thread.




Various ways Of Asynchronous Call :

  1. Delegate Call
  2. Threading
  3. Background worker
  4. ThreadPool
  5. Async and Await
Delegate Call :
               Delegate call is one of the way to call the method in async way. How we can achieve this. Declare the Delegate with signature same as method ,then pass the method name as parameter to the constructor of the delegate that created. Then call the BeginInvoke Which will call the method in async way . Another method Invoke is there which will call the method in sync way.

              When call the Method in Async way need to pass the two parameters, Which one is callback method which is to be called after the execution of method and second one is an parameter to the callback.
If there is no callback then both the parameter for delegate can specify as null.

               Now we take an example method called Run which should be called in Async mode by a delegate RunDelegate. Run Method run for 20 seconds and then return back to the main method.How we can make the main thread to wait for untill the async thread is finished.This is can be done by make a Flag should be set as True in Callback method.

class Program
    {
        public delegate void RunDelegate();  //Delegate with same signature as Run Method
        public static bool flag;

        static void Run()
        {
            DateTime start = DateTime.Now;
            DateTime end = DateTime.Now;
            TimeSpan span = end - start;
            while (span.Seconds < 21)
            {
                end = DateTime.Now;
                span = end - start;
            }
        }

        static void RunCallback(IAsyncResult result)
        {
            flag = true; //Update the flag as True in callback
        }

        static void Main(string[] args)
        {
          RunDelegate test1 = new RunDelegate(Run); //Method name as param to delegate object
          test1.BeginInvoke(RunCallback, null);     //Call the Method in async mode                  

            while (!flag)
            {

            }

            Console.WriteLine("All Task are finished");
            Console.Read();
        }
    }


Output :


Threading:

      Threading is another concept to run a method in async mode , A delegate call is made internally in thread call .Let we see now  ThreadStart Which take the method name as the parameter then Object of ThreadStart  is pass as parameter to Thread. Internally sees in framework ThreadStart is declared as 

    public delegate void ThreadStart();

    class Program
    {
        static ManualResetEvent flag = new ManualResetEvent(false);

        static void Run()
        {
            DateTime start = DateTime.Now;
            DateTime end = DateTime.Now;
            TimeSpan span = end - start;
            while (span.Seconds < 21)
            {
                end = DateTime.Now;
                span = end - start;
            }
            flag.Set();  // Signaling the main thread that work finish
        }
       
        static void Main(string[] args)
        {
            Thread th1=new Thread(new ThreadStart(Run));
            th1.Start();           
            flag.WaitOne(); // Wait for the signal from thread to move for the next step
            Console.WriteLine("All Task are finished");
            Console.Read();
        }
    }


Manual reset event is used to signal the main thread that task is finish because it is waiting in the main thread for signal.

Output :


Background Worker :

     Another way of calling a long running process in asynchronous mode is Background Worker , which is avoiding the UI Non-Responsiveness.

There is a slighter difference between this and other, Because Background worker will give a consecutive ReportProgress from the background thread.Have the following events to occur .

Events :
DoWork                      -   Event which is used to bind the handler which has to do Task
ProgressChanged             -   Event used to bind the handler which will handle the progress
RunWorkerCompleted          -   Event will fire at the completion of Task

Properties :
WorkerReportsProgress       -   Property used to set whether the Report progress has to do.
WorkerSupportsCancellation  -   Property used to set whether Task can be cancel.

Methods :
RunWorkerAsync              -   Method used to run the Task in Background
CancelAsync                 -   Method used to cancel the Task
ReportProgress              -   Method used to report the Progress.


In Our Example
we are going to do a Task in Background for 20 seconds, and report back status to main UI the for every 1 second.Finally after finish the Task completed event will be fired.


  class Program
    {
        static BackgroundWorker worker = new BackgroundWorker();

        static void Run()
        {
            DateTime start = DateTime.Now;
            DateTime end = DateTime.Now;
            TimeSpan span = end - start;
            int prev = 0;
            int curr=0;
            while (span.Seconds < 21)
            {
             if (prev != curr)
             {
               worker.ReportProgress(span.Seconds); //Report will be sent for every second.
               prev = span.Seconds
             }

              end = DateTime.Now;
              span = end - start;
              curr = span.Seconds;
            }          
        }
       
        static void Main(string[] args)
        {
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            worker.WorkerReportsProgress = true;
            worker.WorkerSupportsCancellation = true;           
           
            //To Start the work
            worker.RunWorkerAsync();

            //To Cancel the Background worker un comment the following line.
            //worker.CancelAsync();

            Console.Read();
        }

        static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Console.WriteLine("All Task are finished");
        }

        static void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Console.WriteLine("Seconds : "+e.ProgressPercentage);
        }

        static void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            Run();
        }
    }


Output :



ThreadPool :

   Thread Pool is a collection of threads doing tasks in background.In Thread Pool the main advantage is once a thread is finished the Task then it is returned back to the Thread Pool  and Queued as Waiting Threads.Where it can be reused.It avoid the cost of creating  the new threads.

   If the Thread pool reaches a maximum limit then the additional task are placed in Queue until the available of threads to do the Task.

We can Wait for all threads to Finish by using the ManualResetEvent or CountdownEvent

 var items = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        CountdownEvent countdown = new CountdownEvent(items.Length))
        
            foreach (var item in items)
            {
                ThreadPool.QueueUserWorkItem(o =>
                {
                    Thread.SpinWait(3000);
                    Console.WriteLine("Thread Done!");
                    countdown.Signal();
                });
            }
            countdown.Wait();
        
        Console.WriteLine("Job Done!");

Output :

Thread Done!
Thread Done!
Thread Done!
Thread Done!
Thread Done!
Thread Done!
Thread Done!
Thread Done!
Thread Done!
Thread Done!
Job Done!


ASync And Await :
    Async and Await are new features in c# to run a task in background and wait for the task to finish.

Async method must have the return type of Task,Task<T>, void (async)


class Program
    {

        public static Task<int> GetAddedNumbers(int a, int b)
        {
            return Task.Run(() => Enumerable.Range(a,b).Sum());
        }

        public static async void AddNumberAsync()
        {
            int total = 0;
            for (int i = 0; i < 5; i++)
            {
                total = await GetAddedNumbers(i * 100, i * 10000);
            }
            Console.Write("Total : " + total);
        }
        static void Main(string[] args)
        {

            AddNumberAsync();
            Console.Read();
        }
    }


Output :

Total : 815980000


  
From this Article we can see the asynchronous programming in various way using C# and There usage in the Application.I Hope this will make a better clearance about Asynchronous programming