Just Code‎ > ‎

C# - Asyncronously execute an Action for a period of time and report the amount of executions when done

posted Mar 20, 2012, 2:56 AM by Peter Henell   [ updated Mar 20, 2012, 2:58 AM ]
Just a snippet to execute a given Action in parallel, using a supplied number of max threads, until a specified time or until EndExecute is called.
Will callback the amount of times the Action was executed during that time.

Note, Counter++ is probably not thread safe so don't rely on it.

Only use this snippet as an example of Parallel.ForEach and asynchronous execution of Action.

The BeginExecute method will start executing the Action, the caller will supply a callback Action that will be called when the execution is done. Meanwhile, the caller is not blocked.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Common;
using System.Data.SqlClient;

namespace SQLRepeater.TaskExecuter
{
    public class TaskExecuter
    {
        

        private static System.Threading.CancellationTokenSource _cancelTokenSource;

        private static System.Threading.CancellationTokenSource CancelTokenSource
        {
            get {
                if (_cancelTokenSource == null)
                    _cancelTokenSource = new System.Threading.CancellationTokenSource();
                
                return _cancelTokenSource; 
            }
            set { _cancelTokenSource = value; }
        }

        public void EndExecute()
        {
            CancelTokenSource.Cancel();                        
        }

        public Action CreateSQLTask(string query, string connectionString)
        {
            return new Action(() =>
            {
                using (SqlConnection con = new SqlConnection(connectionString))
                {
                    using (SqlCommand cmd = new SqlCommand(query, con))
                    {
                        cmd.Connection.Open();
                        cmd.ExecuteNonQuery();
                    }
                }
            });
        }

        private int Counter { get; set; }
        public void BeginExecute(Action task, DateTime until, int numTasks, Action<int> onCompletedCallback)
        {
            Action a = () =>
            {
                List<Action> actions = new List<Action>();
                for (int i = 0; i < numTasks; i++)
                {
                    actions.Add(task);
                }

                while (DateTime.Now < until && !CancelTokenSource.IsCancellationRequested)
                {
                    Parallel.ForEach(actions, action =>
                    {
                        action();
                        Counter++;
                    });
                }
            };

            a.BeginInvoke(ar =>
            {
                onCompletedCallback(Counter);
            }, null);

        }


       

        
    }
}
Comments