public virtual void TriggerEvent(UnityTask task, EventCallback cb = null)
        {
            if (task.ExecutionTarget == ExecutionTargetContext.Async || task.ExecutionTarget == ExecutionTargetContext.NextAsyncFrame ||
                task.ExecutionTarget == ExecutionTargetContext.EveryAsyncFrame)
            {
                m_AsyncThreadPool.EventWaitHandle.Set();
            }

            TaskScheduleEvent e = new TaskScheduleEvent(task);

            if (m_EventBus == null)
            {
                m_Tasks.Add(task);
                cb?.Invoke(task.Owner, null);
                return;
            }

            m_EventBus.Emit(task.Owner, e, @event =>
            {
                task.IsCancelled = e.IsCancelled;

                if (!e.IsCancelled)
                {
                    m_Tasks.Add(task);
                }

                cb?.Invoke(task.Owner, @event);
            });
        }
        public ITask ScheduleAt(object @object, Action action, string taskName, DateTime date, bool runAsync = false)
        {
            UnityTask task = new UnityTask(++m_NextTaskId, taskName, this, @object, action,
                                           runAsync ? ExecutionTargetContext.Async : ExecutionTargetContext.Sync)
            {
                StartTime = date
            };

            TriggerEvent(task);
            return(task);
        }
        public ITask SchedulePeriodically(object @object, Action action, string taskName, TimeSpan period,
                                          TimeSpan?delay = null, bool runAsync = false)
        {
            UnityTask task = new UnityTask(++m_NextTaskId, taskName, this, @object, action,
                                           runAsync ? ExecutionTargetContext.Async : ExecutionTargetContext.Sync)
            {
                Period = period
            };

            if (delay != null)
            {
                task.StartTime = DateTime.Now + delay;
            }

            TriggerEvent(task);
            return(task);
        }
        public virtual ITask ScheduleUpdate(object @object, Action action, string taskName, ExecutionTargetContext target)
        {
            UnityTask task = new UnityTask(++m_NextTaskId, taskName, this, @object, action, target);

            TriggerEvent(task, (sender, @event) =>
            {
                if (target != ExecutionTargetContext.Sync)
                {
                    return;
                }

                if (@event != null && ((ICancellableEvent)@event).IsCancelled)
                {
                    return;
                }

                action();
                m_Tasks.Remove(task);
            });

            return(task);
        }