public void Cancel(int id)
        {
            var task = _tasks.Find(x => (x.Status == TaskStatus.Waiting) & x.Id == id);

            if (task != null)
            {
                task.Status = TaskStatus.Canceled;
                if (OnTaskCancel != null)
                {
                    var args = new TaskIdEventArgs(task.Id);
                    OnTaskCancel(this, args);
                }
            }
        }
        public void Delete(List <int> idList)
        {
            var tasks = _tasks.FindAll(x => (
                                           x.Status == TaskStatus.Failed | x.Status == TaskStatus.Completed | x.Status == TaskStatus.Canceled)
                                       & idList.Contains(x.Id));

            if (tasks.Count > 0)
            {
                foreach (var task in tasks)
                {
                    _tasks.Remove(task);
                }

                if (OnTaskDelete != null)
                {
                    var args = new TaskIdEventArgs(0);
                    OnTaskDelete(this, args);
                }
            }
        }
        public void ReStart(int id)
        {
            var task = _tasks.Find(x => (x.Status == TaskStatus.Canceled | x.Status == TaskStatus.Failed | x.Status == TaskStatus.Completed) & x.Id == id);

            if (task != null)
            {
                var processingTasks = _tasks.Where(x => x.Status == TaskStatus.Processing);
                var processingTaskIdentityFlagList = processingTasks.Where(x => !x.IdentityFlag.IsNullOrEmpty()).Select(x => x.IdentityFlag).Distinct().ToList();
                if (task.IdentityFlag.IsNullOrEmpty() | !processingTaskIdentityFlagList.Contains(task.IdentityFlag))
                {
                    int  i;
                    bool isWorkerPoolBusy = true;
                    for (i = 0; i < _workerCount; i++)
                    {
                        if (!_workers[i].IsBusy)
                        {
                            RaiseDoWork(_workers[i], task);
                            task.WorkerId    = i;
                            isWorkerPoolBusy = false;
                            break;
                        }
                    }

                    if (isWorkerPoolBusy)
                    {
                        task.Status = TaskStatus.Waiting;
                    }
                }
                else
                {
                    task.Status = TaskStatus.Waiting;
                }

                if (OnTaskRestart != null)
                {
                    var args = new TaskIdEventArgs(_id);
                    OnTaskRestart(this, args);
                }
            }
        }