/// <summary>
        /// Creates a new task and starts executing it.
        /// </summary>
        /// <returns>
        /// The new executing task.
        /// </returns>
        /// <param name='taskFactory'>
        /// Task factory to start with.
        /// </param>
        /// <param name='coroutine'>
        /// The coroutine to start.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <param name='creationOptions'>
        /// Creation options.
        /// </param>
        /// <param name='scheduler'>
        /// Scheduler.
        /// </param>
        public static Task StartNew(this TaskFactory taskFactory, IEnumerator coroutine, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
        {
            var task = new YieldableTask(coroutine, cancellationToken, creationOptions);

            task.Start(scheduler);
            return(task);
        }
        /// <summary>
        /// Creates a new task and starts executing it.
        /// </summary>
        /// <returns>
        /// The new executing task.
        /// </returns>
        /// <param name='taskFactory'>
        /// Task factory to start with.
        /// </param>
        /// <param name='instruction'>
        /// The instruction to start.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <param name='creationOptions'>
        /// Creation options.
        /// </param>
        /// <param name='scheduler'>
        /// Scheduler.
        /// </param>
        public static Task StartNew(this TaskFactory taskFactory, FiberInstruction instruction, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
        {
            var task = new YieldableTask(instruction, cancellationToken, creationOptions);

            task.Start(scheduler);
            return(task);
        }
        /// <summary>
        /// Continues the task with a coroutine.
        /// </summary>
        /// <returns>
        /// The continued task.
        /// </returns>
        /// <param name='task'>
        /// Task to continue.
        /// </param>
        /// <param name='instruction'>
        /// The instruction to continue with.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <param name='continuationOptions'>
        /// Continuation options.
        /// </param>
        /// <param name='scheduler'>
        /// Scheduler to use when scheduling the task.
        /// </param>
        public static Task ContinueWith(this Task task, FiberInstruction instruction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
        {
            if (instruction == null)
            {
                throw new ArgumentNullException("instruction");
            }
            if (scheduler == null)
            {
                throw new ArgumentNullException("scheduler");
            }
            if (!(scheduler is FiberTaskScheduler))
            {
                throw new ArgumentException("The scheduler for a YieldableTask must be a FiberTaskScheduler", "scheduler");
            }

            // This creates a continuation that runs on the default scheduler (e.g. ThreadPool)
            // where it's OK to wait on a child task to complete. The child task is scheduled
            // on the given scheduler and attached to the parent.

            //var outerScheduler = TaskScheduler.Current;
            //if(outerScheduler is MonoBehaviourTaskScheduler)
            //  outerScheduler = TaskScheduler.Default;

            var outerScheduler = TaskScheduler.Default;

            // The thread pool scheduler cannot be used in web scenarios. The outer scheduler
            // must be the fiber scheduler.
            //var outerScheduler = scheduler;

            return(task.ContinueWith((Task antecedent) => {
                var yieldableTask = new YieldableTask(instruction, cancellationToken, TaskCreationOptions.AttachedToParent);
                yieldableTask.Start(scheduler);
            }, cancellationToken, continuationOptions, outerScheduler));
        }
 /// <summary>
 /// Creates a new task and starts executing it.
 /// </summary>
 /// <returns>
 /// The new executing task.
 /// </returns>
 /// <param name='taskFactory'>
 /// Task factory to start with.
 /// </param>
 /// <param name='instruction'>
 /// The instruction to start.
 /// </param>
 /// <param name='cancellationToken'>
 /// Cancellation token.
 /// </param>
 /// <param name='creationOptions'>
 /// Creation options.
 /// </param>
 /// <param name='scheduler'>
 /// Scheduler.
 /// </param>
 public static Task StartNew(this TaskFactory taskFactory, FiberInstruction instruction, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
 {
     var task = new YieldableTask (instruction, cancellationToken, creationOptions);
     task.Start (scheduler);
     return task;
 }
 /// <summary>
 /// Creates a new task and starts executing it.
 /// </summary>
 /// <returns>
 /// The new executing task.
 /// </returns>
 /// <param name='taskFactory'>
 /// Task factory to start with.
 /// </param>
 /// <param name='coroutine'>
 /// The coroutine to start.
 /// </param>
 /// <param name='cancellationToken'>
 /// Cancellation token.
 /// </param>
 /// <param name='creationOptions'>
 /// Creation options.
 /// </param>
 /// <param name='scheduler'>
 /// Scheduler.
 /// </param>
 public static Task StartNew(this TaskFactory taskFactory, IEnumerator coroutine, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
 {
     var task = new YieldableTask (coroutine, cancellationToken, creationOptions);
     task.Start (scheduler);
     return task;
 }
        /// <summary>
        /// Continues the task with a coroutine.
        /// </summary>
        /// <returns>
        /// The continued task.
        /// </returns>
        /// <param name='task'>
        /// Task to continue.
        /// </param>
        /// <param name='instruction'>
        /// The instruction to continue with.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <param name='continuationOptions'>
        /// Continuation options.
        /// </param>
        /// <param name='scheduler'>
        /// Scheduler to use when scheduling the task.
        /// </param>
        public static Task ContinueWith(this Task task, FiberInstruction instruction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
        {
            if (instruction == null)
                throw new ArgumentNullException ("instruction");
            if (scheduler == null)
                throw new ArgumentNullException ("scheduler");
            if (!(scheduler is FiberTaskScheduler))
                throw new ArgumentException ("The scheduler for a YieldableTask must be a FiberTaskScheduler", "scheduler");

            // This creates a continuation that runs on the default scheduler (e.g. ThreadPool)
            // where it's OK to wait on a child task to complete. The child task is scheduled
            // on the given scheduler and attached to the parent.

            //var outerScheduler = TaskScheduler.Current;
            //if(outerScheduler is MonoBehaviourTaskScheduler)
            //  outerScheduler = TaskScheduler.Default;

            var outerScheduler = TaskScheduler.Default;

            return task.ContinueWith((Task antecedent) => {
                var yieldableTask = new YieldableTask(instruction, cancellationToken, TaskCreationOptions.AttachedToParent);
                yieldableTask.Start(scheduler);
            }, cancellationToken, continuationOptions, outerScheduler);
        }
        private IEnumerator TestFuncTaskCoroutine()
        {
            var scheduler = new FiberTaskScheduler();

            var task = new YieldableTask(() => new YieldForSeconds(2));
            task.Start(scheduler);

            while (!task.IsCompleted)
                yield return FiberInstruction.YieldToAnyFiber;
        }