Pages

Search

Thursday, April 5, 2012

Asynchronous Models


There are different ways like Asynchronous Programming Model or Event Asynchronous Pattern or Task Asynchronous Pattern which enable the asynchronous behavior of invoking the functions.
Usually in APM (Asynchronous Programming Model), developer has to call the beinginvoke and endinvoke functions which work with delegates to support async.  
In case of EAP (Event Asynchronous Pattern which enable), usually we create async function which has suffix as “Async”. It is required to fire an event when the async operation is completed. So when the caller is invoking the async function, caller has to register to the event which gets fired after async operation is completed.
In case of TAP (Task Asynchronous Pattern), same as like EAP the methods are suffixed as “TaskAsync” or “Aysc” to make caller ease to understand. The function returns the “Task” object to the caller, to which caller can say “continuewith” or can track it self the state of async operation.
Below source demonstrates the Sync behavior, APM, EAP and TAP.
Forms.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Runtime.Remoting.Messaging;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                //synchronous method behaviour
                MessageBox.Show("Synchronous : " + SumRootN(100));

                //Asynchronous Programming Model (APM)
                IAsyncResult ar = BeginSumRootN(200, null, null);
                do { } while (!ar.IsCompleted);
                MessageBox.Show("APM : " + EndSumRootN(ar));

                //Event Asynchronous Pattern (EAP)
                OnSumRootNCompleted += new SumRootNCompletedEventHandler(Form1_OnSumRootNCompleted);
                SumRootNAsync(5);

                //Task Asynchronous Pattern (TAP)
                Task<double> objSumTask = SumRootNTaskAsync(100);
                objSumTask.ContinueWith(
                    (t) =>
                    {
                        MessageBox.Show("TAP : " + t.Result);
                    }, CancellationToken.None);
            }
            catch (Exception exp)
            {
                MessageBox.Show("Error : " + exp.Message);
            }
        }


        //methhod thats gets fired when the opertaion is completed via EAP
        void Form1_OnSumRootNCompleted(object sender, SumRootNCompletedEventArgs e)
        {
            MessageBox.Show("EAP : " + e.Result);
        }

        #region SyncronousModel
        public double SumRootN(int root)
        {
            double result = 0;
            for (int i = 1; i < 1000000; i++)
            {
                result += Math.Exp(Math.Log(i) / root);
            }
            return result;
        }
        #endregion

        #region APM (Asynchornous Programming Model)
        public delegate double delSumRootN(int root);
        public IAsyncResult BeginSumRootN(int root, AsyncCallback callback, object state)
        {
            delSumRootN objDelSumRootN = new delSumRootN(SumRootN);
            return objDelSumRootN.BeginInvoke(root, callback, objDelSumRootN);
        }

        public double EndSumRootN(IAsyncResult ar)
        {
            return (ar.AsyncState as delSumRootN).EndInvoke(ar);
        }
        #endregion

        #region Using EAP (Event Asynchronous Pattern)
        public class SumRootNCompletedEventArgs : AsyncCompletedEventArgs
        {
            public double Result;

            public SumRootNCompletedEventArgs(Exception exp, bool bCanceled, object state)
                : base(exp, bCanceled, state)
            {
            }
        }

        public void SumRootNAsync(int root)
        {
            AsyncOperation objOperation = AsyncOperationManager.CreateOperation(root);
            Action<int, AsyncOperation> act = new Action<int, AsyncOperation>(BeginSumRootNAsync);
            act.BeginInvoke(root, objOperation, null, null);
        }

        public void BeginSumRootNAsync(int root, AsyncOperation oper)
        {
            double res = 0;
            SumRootNCompletedEventArgs e = null;
            try
            {
                res = SumRootN(root);
                e = new SumRootNCompletedEventArgs(null, false, root);
                e.Result = res;
            }
            catch (Exception exp)
            {
                e = new SumRootNCompletedEventArgs(exp, false, root);
            }
            oper.PostOperationCompleted(
               (o) =>
               {
                   if (OnSumRootNCompleted != null)
                       OnSumRootNCompleted(root, e);

               }, root);
        }
        public delegate void SumRootNCompletedEventHandler(object sender, SumRootNCompletedEventArgs e);
        public event SumRootNCompletedEventHandler OnSumRootNCompleted;
        #endregion

        #region TAP (Task Asynchronous Pattern)
        public Task<double> SumRootNTaskAsync(int root)
        {
            Task<double> objTask = Task.Factory.StartNew<double>(
                () => { return SumRootN(root); }, CancellationToken.None);
            return objTask;
        }
        #endregion
    }
}


No comments:

Post a Comment