1 TaskQueue 实现Task 队列

 

    class Program
    {
        static void Main(string[] args)
        {
            List<Person> list = new List<Person>();
            for (int i = 0; i < 10; i++)
                list.Add(new Person("AA" + i));

            TaskQueue<Person> task = new TaskQueue<Person>();
            task.MaxDataCountEverySubTask = 1;
            task.MaxRunningSubTaskCount = 10;
            task.ExecuteData += task_ExecuteData;
            task.TaskCompleted += task_TaskCompleted;
            Console.WriteLine(DateTime.Now.ToString("mm ss fff"));
            task.QueueUserTaskDataAsync(list);

            Console.WriteLine("主线程Ok");
            Console.ReadKey();
        }
        public static void LongTimeMethod()
        {
            var list2 = new List<string>();
            for (int i = 0; i < 5000000; i++)
            {
                list2.Add(i.ToString());
            }
            list2 = null;
        }
        static void task_ExecuteData(List<Person> executeData)
        {
            try
            {
                LongTimeMethod();

                executeData.ForEach(a => Console.WriteLine("{0} {1}", a.Name, DateTime.Now.ToString("mm ss fff")));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
        static void task_TaskCompleted()
        {
            Console.WriteLine("执行完成");
        }
        public class Person
        {
            public string Name { get; set; }
            public Person(string name)
            {
                this.Name = name;
            }
        }
    }
TaskQueue
    /// <summary>
    /// 任务队列
    /// </summary>
    /// <typeparam name="T">任务要处理的数据的数据类型</typeparam>
    /// 示例在末尾
    public class TaskQueue<T>
    {
        #region 成员、属性、事件
        /// <summary>
        /// 数量锁
        /// </summary>
        private string _countLock = "LockCount";
        /// <summary>
        /// 总数量锁
        /// </summary>
        private string _countLockMain = "LockCountMain";
        private bool _isAsyn = false;
        /// <summary>
        /// 当在分配子任务时,遇到最大可执行任务数阻塞时,线程休眠的时长。
        /// </summary>
        private int _sleepMilliSecondsWhenQueueSubTask = 100;
        /// <summary>
        /// 当在分配子任务时,遇到最大可执行任务数阻塞时,线程休眠的时长。
        /// </summary>
        /// <exception cref="ArgumentOutOfRangeException">
        /// value小于等于0时触发。
        /// </exception>
        public int SleepMilliSecondsWhenQueueSubTask
        {
            get { return _sleepMilliSecondsWhenQueueSubTask; }
            set
            {
                if (value <= 0)
                {
                    throw new ArgumentOutOfRangeException("value值必须大于0。");
                }
                _sleepMilliSecondsWhenQueueSubTask = value;
            }
        }
        /// <summary>
        /// 当在在等待子任务完成时,每次线程休眠的时长。
        /// </summary>
        private int _sleepMilliSecondsWhenWaitComplete = 100;
        /// <summary>
        /// 当在在等待子任务完成时,每次线程休眠的时长。
        /// </summary>
        /// <exception cref="ArgumentOutOfRangeException">
        /// value小于等于0时触发。
        /// </exception>
        public int SleepMilliSecondsWhenWaitComplete
        {
            get { return _sleepMilliSecondsWhenWaitComplete; }
            set
            {
                if (value <= 0)
                {
                    throw new ArgumentOutOfRangeException("value值必须大于0。");
                }
                _sleepMilliSecondsWhenWaitComplete = value;
            }
        }
        /// <summary>
        /// 允许同时执行的子任务个数
        /// </summary>
        private int _maxRunningThreadCount = 20;
        /// <summary>
        /// 允许同时执行的子任务个数
        /// </summary>
        /// <exception cref="ArgumentOutOfRangeException">
        /// value等于0时触发。
        /// </exception>
        public int MaxRunningSubTaskCount
        {
            get { return _maxRunningThreadCount; }
            set
            {
                if (value <= 0)
                {
                    throw new ArgumentOutOfRangeException("value值必须大于0。");
                }
                lock (_countLock)
                {
                    _maxRunningThreadCount = value;
                }
            }
        }
        /// <summary>
        /// 每个子任务要处理的数据个数
        /// </summary>
        private int _maxDataCountEverySubTask = 50;
        /// <summary>
        /// 每个子任务要处理的数据个数
        /// </summary>
        /// <exception cref="ArgumentOutOfRangeException">
        /// value等于0时触发。
        /// </exception>
        public int MaxDataCountEverySubTask
        {
            get { return _maxDataCountEverySubTask; }
            set
            {
                if (value <= 0)
                {
                    throw new ArgumentOutOfRangeException("value值必须大于0。");
                }
                lock (_countLock)
                {
                    _maxDataCountEverySubTask = value;
                }
            }
        }
        /// <summary>
        /// 当前已分配子任务个数
        /// </summary>
        private int _currentSubTaskCount = 0;
        /// <summary>
        /// 当前已分配子任务个数
        /// </summary>
        public int CurrentSubTaskCount
        {
            get { return _currentSubTaskCount; }
        }
        /// <summary>
        /// 当前已执行成功的子任务个数
        /// </summary>
        private int _currentSuccessSubTaskCount = 0;
        /// <summary>
        /// 当前已执行成功的子任务个数
        /// </summary>
        public int CurrentSuccessSubTaskCount
        {
            get { return _currentSuccessSubTaskCount; }
        }
        /// <summary>
        /// 当前已执行失败的线程个数
        /// </summary>
        private int _currentFailSubTaskCount = 0;
        /// <summary>
        /// 当前已执行失败的线程个数
        /// </summary>
        public int CurrentFailSubTaskCount
        {
            get { return _currentFailSubTaskCount; }
        }

        /// <summary>
        /// 每个子任务执行的委托
        /// </summary>
        /// <param name="sender">发送者</param>
        /// <param name="executeData">要处理的数据</param>
        //public delegate void ExecuteDelegate(TaskQueue<T> taskQueue, List<T> executeData);
        public delegate void ExecuteDelegate(List<T> executeData);
        /// <summary>
        /// 需要子任务处理数据时触发
        /// </summary>
        public event ExecuteDelegate ExecuteData;
        /// <summary>
        /// 触发子任务处理数据
        /// </summary>
        /// <param name="executeData"></param>
        protected void OnExecuteData(List<T> executeData)
        {
            if (ExecuteData != null)
            {
                //ExecuteData(this, executeData);
                ExecuteData(executeData);
            }
        }
        /// <summary>
        /// 所有子任务处理结束后要执行的委托
        /// </summary>
        /// <param name="sender">发送者</param>
        //public delegate void TaskCompletedDelegate(TaskQueue<T> taskQueue);
        public delegate void TaskCompletedDelegate();
        /// <summary>
        /// (异步模式下才会触发)所有子任务处理结束后触发
        /// </summary>
        public event TaskCompletedDelegate TaskCompleted;
        /// <summary>
        /// 通知任务队列拥有者任务已执行完成。
        /// </summary>
        protected void OnTaskExecuted()
        {
            if (TaskCompleted != null)
            {
                //TaskCompleted(this);
                TaskCompleted();
            }
        }
        /// <summary>
        /// 任务要处理的所有数据
        /// </summary>
        private List<T> _taskData;
        /// <summary>
        /// 任务要处理的所有数据
        /// </summary>
        public List<T> TaskData
        {
            get { return _taskData; }
        }

        #endregion

        #region 方法
        /// <summary>
        /// (异步模式)写入任务队列要处理的数据。函数会立刻返回。
        /// </summary>
        /// <param name="taskData">要处理的数据</param>
        /// <exception cref="ArgumentNullException">
        /// taskData为null时触发。
        ///   </exception>
        ///   
        /// <exception cref="ArgumentOutOfRangeException">
        /// taskData元素个数等于0时触发。
        ///   </exception>
        public void QueueUserTaskDataAsync(List<T> taskData)
        {
            _isAsyn = true;
            ThreadPool.QueueUserWorkItem(QueueTask, taskData);
        }

        /// <summary>
        /// (同步模式)写入任务队列要处理的数据。函数会在所有子任务执行结束后返回。
        /// </summary>
        /// <param name="taskData">要处理的数据</param>
        /// <exception cref="ArgumentNullException">
        /// taskData为null时触发。
        ///   </exception>
        ///   
        /// <exception cref="ArgumentOutOfRangeException">
        /// taskData元素个数等于0时触发。
        ///   </exception>
        public void QueueUserTaskData(List<T> taskData)
        {
            QueueTask(taskData);
        }

        /// <summary>
        /// 写入任务队列要处理的数据
        /// </summary>
        /// <param name="taskData">要处理的数据</param>
        /// <exception cref="ArgumentNullException">
        /// taskData为null时触发。
        ///   </exception>
        ///   
        /// <exception cref="ArgumentOutOfRangeException">
        /// taskData元素个数等于0时触发。
        ///   </exception>
        private void QueueTask(object taskData)
        {
            _taskData = taskData as List<T>;
            if (_taskData == null)
                throw new ArgumentNullException("taskData不能为空。");
            if (_taskData.Count <= 0)
                throw new ArgumentOutOfRangeException("taskData元素个数至少有一个。");
            // 初始化数据
            lock (_countLock)
            {
                _currentSubTaskCount = _currentSuccessSubTaskCount = _currentFailSubTaskCount = 0;
            }
            // 分配数据给子任务,直到所有数据分配完毕
            do
            {
                // 取出子任务需处理的数据
                List<T> executeData = _taskData.Take(_maxDataCountEverySubTask).ToList();
                // 从总数据中移除
                _taskData.RemoveRange(0, executeData.Count);
                // 如果正在执行的子任务达到了最大限定数目,则休眠一次
                while (_maxRunningThreadCount <= _currentSubTaskCount - _currentSuccessSubTaskCount - _currentFailSubTaskCount)
                {
                    Thread.Sleep(_sleepMilliSecondsWhenQueueSubTask);
                }
                // 分配子任务
                ThreadPool.QueueUserWorkItem(ExecuteDataTask, executeData);
                // 累计总子任务数
                lock (_countLockMain)
                {
                    _currentSubTaskCount++;
                }
            }
            while (_taskData.Count > 0);
            // 等待所有子任务执行结束
            while (_currentSubTaskCount > _currentSuccessSubTaskCount + _currentFailSubTaskCount)
            {
                Thread.Sleep(_sleepMilliSecondsWhenWaitComplete);
            }
            // 如果是异步模式,则需要通知队列拥有者任务已完成
            if (_isAsyn)
            {
                ThreadPool.QueueUserWorkItem(FireTaskExecuted);
            }
        }

        /// <summary>
        /// 异步触发TaskExecuted事件
        /// </summary>
        /// <param name="state"></param>
        private void FireTaskExecuted(object state)
        {
            // 通知队列拥有者任务已完成
            OnTaskExecuted();
        }

        /// <summary>
        /// 子任务处理数据
        /// </summary>
        /// <param name="data">子任务所需处理数据</param>
        private void ExecuteDataTask(object data)
        {
            bool success = true;
            try
            {
                List<T> executeData = data as List<T>;
                // 通知队列拥有者处理数据
                OnExecuteData(executeData);
            }
            catch
            {
                success = false;
            }
            // 累计子任务运行结束的数量
            if (success)
            {
                // 累计到成功数上
                lock (_countLock)
                {
                    _currentSuccessSubTaskCount++;
                }
            }
            else
            {
                // 累计到失败数上
                lock (_countLock)
                {
                    _currentFailSubTaskCount++;
                }
            }
        }
        #endregion
    }

    #region 示例
    //static void Main(string[] args)
    //{
    //    List<Person> list = new List<Person>() { new Person("AA"), new Person("BB"), new Person("CC") };
    //    TaskQueue<Person> task =new TaskQueue<Person>();
    //    task.ExecuteData += task_ExecuteData;
    //    task.TaskCompleted += task_TaskCompleted;
    //    task.QueueUserTaskDataAsync(list);
    //    Console.WriteLine("主线程Ok");
    //    Console.ReadKey();
    //}
    //static void task_ExecuteData( List<Person> executeData)
    //{
    //    try
    //    {
    //        Thread.Sleep(3000);
    //        executeData.ForEach(a => Console.WriteLine(a.Name));
    //    }
    //    catch (Exception ex)
    //    {
    //        Console.WriteLine(ex.ToString());
    //    }
    //}
    //static void task_TaskCompleted()
    //{
    //    Console.WriteLine("执行完成");
    //}
    //public class Person
    //{
    //    public string Name { get; set; }
    //    public Person(string name)
    //    {
    //        this.Name = name;
    //    }
    //}
    #endregion

 

posted @ 2018-12-22 23:09  一只桔子2233  阅读(1985)  评论(0编辑  收藏  举报