Tuesday, 11 March 2014

How to speed up processing based on table records using threading in C#, DotNet

Description: This post will give you logic to speed up processing based on data coming from table by using threading. In this, logic simply divides records of table that needs to be processed using Number of Instance that we provide.
There are two main classes used for it.

1.    WorkAllocator class
2.    WorkerThread class

1.    WorkAllocator class:
   Creates worker threads


    class WorkAllocator
    {  
        private int mInstanceToBeCreated = Convert.ToInt16(Properties.Settings.Default.InstanceCount);
        //Define Instance in config
       
        static void Main(string[] args)
        {  

            #region Create Threads to process data Table records
                DataTable dtData = new DataTable(); // Data Source           
                dtData = GetTableDataToProcess();  //Get the Data using Any DataSource
                int mPerInstanceWorkSize = dtData.Rows.Count;
                int mCurrentRowIndex = 0;
                if (dtData != null)
                {
                    if (dtData.Rows.Count > 0)
                    {
                        if (mInstanceToBeCreated > 1)
                        {
                            //Calculate work/rows size that should be processed by a given thread
                            mPerInstanceWorkSize = dtData.Rows.Count / mInstanceToBeCreated;
                        }
                        for (int i = 1; i <= mInstanceToBeCreated; i++)
                        {
                            //Create No Of threads using mInstanceCount {} which can be defined in config
                            WorkerThread objWorker = new WorkerThread(mCurrentRowIndex, mPerInstanceWorkSize, dtData);
                            Thread objThread = new Thread(new ThreadStart(objWorker.doWork));
                            objThread.Start();
                            mCurrentRowIndex += mPerInstanceWorkSize + 1;
                            Thread.Sleep(10);
                        }
                    }
                }
            #endregion
            GC.Collect();
        }

        private static DataTable GetTableDataToProcess()
        {
            DataTable dtData = new DataTable();
            try
            {
                dtData.Columns.Add("ID");
                dtData.Columns.Add("Name");
                dtData.Columns.Add("Today", System.Type.GetType("System.DateTime"));

                dtData.Rows.Add(1,"ABC",System.DateTime.Now.Date);
                dtData.Rows.Add(2, "ABCD", System.DateTime.Now.Date);
                dtData.Rows.Add(3, "ABCDF", System.DateTime.Now.Date);
                dtData.Rows.Add(4, "ABCFGH", System.DateTime.Now.Date);
                dtData.Rows.Add(5, "ABCFGG", System.DateTime.Now.Date);
                return dtData;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }


2.    WorkerThread:
  For doing the processing based on defined logic for give set of selected records from table



    public class WorkerThread
    {   
        private int CurrentRowIndex, LastRowIndex;
        private DataTable dtData = null;

        public WorkerThread(int mCurrentRowIndex, int mLastRowIndex, DataTable mdtData)
        {
            //At time of thread creation define work boundry for threads
            CurrentRowIndex = mCurrentRowIndex;
            LastRowIndex = mLastRowIndex;
            dtData = mdtData;          
        }

        public void doWork()
        {           
            //Using boundry process records present in agiven range
            for (int mRowIndex = CurrentRowIndex; mRowIndex < dtData.Rows.Count && mRowIndex <= LastRowIndex + CurrentRowIndex; mRowIndex++)
            {
                try
                {
                    DataRow dr = dtData.Rows[mRowIndex];
                    ProcessData(dr);
                }
                catch (Exception ex)
                {
                }
                Console.WriteLine("Row " + (mRowIndex + 1).ToString() + " Processed ");
            }                      
        }

        private void ProcessData(DataRow dr)
        {          
            try
            {
                //Do work
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error : " + ex.ToString());            
            }        
        }   
    }


No comments:

Post a Comment