コード例 #1
0
        /// <summary>
        /// Registers a continuation for the task that will run when the task is complete.
        /// </summary>
        /// <typeparam name="T">The type returned by the continuation.</typeparam>
        /// <param name="p_continuation">The continuation to run after the task completes.
        /// The function takes the completed task as an argument and can return a value.</param>
        /// <returns>A new Task that returns the value returned by the continuation after both
        /// the task and the continuation are complete.</returns>
        public UnityTask ContinueWith(Action <UnityTask> p_continuation, System.Threading.Tasks.CancellationToken p_cancellationToken)
        {
            bool completed = false;

            UnityTaskCompletionSource <int> utcs        = new UnityTaskCompletionSource <int>();
            CancellationTokenRegistration   cancelToken = p_cancellationToken.Register(() => utcs.TrySetCanceled());

            // 此处防止判断为false之后正好执行完毕
            completed = IsCompleted;
            if (!completed)
            {
                m_continuationActions.Add(t =>
                {
                    try
                    {
                        p_continuation(this);
                        utcs.TrySetResult(0);
                        cancelToken.Dispose();
                    }
                    catch (Exception ex)
                    {
                        utcs.TrySetException(ex);
                        cancelToken.Dispose();
                    }
                });
            }
            else
            {
                ForegroundInvoker.Invoke(() =>// 如果当前不在前端线程,则切换
                {
                    try
                    {
                        p_continuation(this);
                        utcs.TrySetResult(0);
                        cancelToken.Dispose();
                    }
                    catch (Exception ex)
                    {
                        utcs.TrySetException(ex);
                        cancelToken.Dispose();
                    }
                });
            }

            return(utcs.Task);
        }
コード例 #2
0
        /// <summary>
        /// Registers a continuation for the task that will run when the task is complete.
        /// </summary>
        /// <typeparam name="T">The type returned by the continuation.</typeparam>
        /// <param name="p_continuation">The continuation to run after the task completes.
        /// The function takes the completed task as an argument and can return a value.</param>
        /// <param name="p_cancellationToken">The cancellation token.</param>
        /// <returns>A new Task that returns the value returned by the continuation after both
        /// the task and the continuation are complete.</returns>
        public UnityTask <UnityTask> ContinueWith(Func <UnityTask, IEnumerator> p_continuation, System.Threading.Tasks.CancellationToken p_cancellationToken)
        {
            Func <UnityTask, UnityTask> continuation = t =>
            {
                return(UnityTask.Run(() => p_continuation(t)));
            };

            return(ContinueWith(continuation, p_cancellationToken));
        }
コード例 #3
0
        /// <summary>
        /// Registers a continuation for the task that will run when the task is complete.
        /// </summary>
        /// <typeparam name="T">The type returned by the continuation.</typeparam>
        /// <param name="p_continuation">The continuation to run after the task completes.
        /// The function takes the completed task as an argument and can return a value.</param>
        /// <param name="p_cancellationToken">The cancellation token.</param>
        /// <returns>A new Task that returns the value returned by the continuation after both
        /// the task and the continuation are complete.</returns>
        public UnityTask <UnityTask> ContinueWith(Func <UnityTask, UnityTask> p_continuation, System.Threading.Tasks.CancellationToken p_cancellationToken)
        {
            bool completed = false;

            UnityTaskCompletionSource <UnityTask> utcs        = new UnityTaskCompletionSource <UnityTask>();
            CancellationTokenRegistration         cancelToken = p_cancellationToken.Register(() => utcs.TrySetCanceled());

            // 此处防止判断为false之后正好执行完毕
            completed = IsCompleted;
            if (!completed)
            {
                m_continuationActions.Add(t =>
                {
                    //if (t.IsFaulted)
                    //{
                    //    utcs.TrySetException(t.Exception);
                    //    cancelToken.Dispose();
                    //}
                    //else
                    //{
                    try
                    {
                        UnityTask result = p_continuation(t);
                        utcs.TrySetResult(result);
                        cancelToken.Dispose();
                    }
                    catch (Exception ex)
                    {
                        utcs.TrySetException(ex);
                        cancelToken.Dispose();
                    }
                    //}
                });
            }
            else
            {
                ForegroundInvoker.Invoke(() =>
                {
                    //if (this.IsFaulted)
                    //{
                    //    utcs.TrySetException(this.Exception);
                    //    cancelToken.Dispose();
                    //}
                    //else
                    //{
                    try
                    {
                        UnityTask result = p_continuation(this);
                        utcs.TrySetResult(result);
                        cancelToken.Dispose();
                    }
                    catch (Exception ex)
                    {
                        utcs.TrySetException(ex);
                        cancelToken.Dispose();
                    }
                    //}
                });
            }

            return(utcs.Task);
        }
コード例 #4
0
ファイル: Task.net35.cs プロジェクト: NN---/Theraot
 internal Task(Action action, Task parent, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler)
     : this(action, null, parent, cancellationToken, creationOptions, internalOptions, scheduler)
 {
     CapturedContext = ExecutionContext.Capture();
 }
コード例 #5
0
ファイル: Task.net35.cs プロジェクト: NN---/Theraot
        /// <summary>
        /// An internal constructor used by the factory methods on task and its descendent(s).
        /// This variant does not capture the ExecutionContext; it is up to the caller to do that.
        /// </summary>
        /// <param name="action">An action to execute.</param>
        /// <param name="state">Optional state to pass to the action.</param>
        /// <param name="parent">Parent of Task.</param>
        /// <param name="cancellationToken">A CancellationToken for the task.</param>
        /// <param name="scheduler">A task scheduler under which the task will run.</param>
        /// <param name="creationOptions">Options to control its execution.</param>
        /// <param name="internalOptions">Internal options to control its execution</param>
        internal Task(Delegate action, object state, Task parent, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler)
        {
            if (action == null)
            {
#pragma warning disable IDE0016
                throw new ArgumentNullException(nameof(action));
#pragma warning restore IDE0016
            }
            if (scheduler == null)
            {
#pragma warning disable IDE0016
                throw new ArgumentNullException(nameof(scheduler));
#pragma warning restore IDE0016
            }
            Contract.EndContractBlock();
            // This is readonly, and so must be set in the constructor
            // Keep a link to your parent if: (A) You are attached, or (B) you are self-replicating.
            if
            (
                (creationOptions & TaskCreationOptions.AttachedToParent) != 0 ||
                (internalOptions & InternalTaskOptions.SelfReplicating) != 0
            )
            {
                _parent = parent;
            }
            Id      = Interlocked.Increment(ref _lastId) - 1;
            _status = (int)TaskStatus.Created;
            if
            (
                _parent != null &&
                (creationOptions & TaskCreationOptions.AttachedToParent) != 0 &&
                (_parent.CreationOptions & TaskCreationOptions.DenyChildAttach) == 0
            )
            {
                _parent.AddNewChild();
            }
            ExecutingTaskScheduler = scheduler;
            Action      = action;
            State       = state;
            _waitHandle = new ManualResetEventSlim(false);
            if ((creationOptions &
                 ~(TaskCreationOptions.AttachedToParent |
                   TaskCreationOptions.LongRunning |
                   TaskCreationOptions.DenyChildAttach |
                   TaskCreationOptions.HideScheduler |
                   TaskCreationOptions.PreferFairness |
                   TaskCreationOptions.RunContinuationsAsynchronously)) != 0)
            {
                throw new ArgumentOutOfRangeException(nameof(creationOptions));
            }
            // Throw exception if the user specifies both LongRunning and SelfReplicating
            if ((creationOptions & TaskCreationOptions.LongRunning) != 0 &&
                (internalOptions & InternalTaskOptions.SelfReplicating) != 0)
            {
                throw new InvalidOperationException("An attempt was made to create a LongRunning SelfReplicating task.");
            }
            if ((internalOptions & InternalTaskOptions.ContinuationTask) != 0)
            {
                // For continuation tasks or TaskCompletionSource.Tasks, begin life in the
                // WaitingForActivation state rather than the Created state.
                _status = (int)TaskStatus.WaitingForActivation;
            }
            CreationOptions  = creationOptions;
            _internalOptions = internalOptions;
            // if we have a non-null cancellationToken, allocate the contingent properties to save it
            // we need to do this as the very last thing in the construction path, because the CT registration could modify m_stateFlags
            if (cancellationToken.CanBeCanceled)
            {
                AssignCancellationToken(cancellationToken, null, null);
            }
        }
コード例 #6
0
ファイル: Task.net35.cs プロジェクト: NN---/Theraot
 public Task(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
     : this(action, null, InternalCurrentIfAttached(creationOptions), cancellationToken, creationOptions, InternalTaskOptions.None, TaskScheduler.Default)
 {
     // Empty
 }
コード例 #7
0
ファイル: Task.net35.cs プロジェクト: NN---/Theraot
 internal Task(Action <object> action, object state, Task parent, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler)
     : this((Delegate)action, state, parent, cancellationToken, creationOptions, internalOptions, scheduler)
 {
     CapturedContext = ExecutionContext.Capture();
 }
コード例 #8
0
ファイル: Task.net35.cs プロジェクト: NN---/Theraot
 public void Wait(CancellationToken cancellationToken)
 {
     PrivateWait(cancellationToken, true);
 }
コード例 #9
0
ファイル: Task.net35.cs プロジェクト: NN---/Theraot
        public bool Wait(int milliseconds, CancellationToken cancellationToken)
        {
            if (milliseconds < -1)
            {
                throw new ArgumentOutOfRangeException(nameof(milliseconds));
            }
            if (milliseconds == -1)
            {
                Wait(cancellationToken);
                return(true);
            }
            var start = ThreadingHelper.TicksNow();

            do
            {
                CancellationCheck(cancellationToken);
                switch (Status)
                {
                case TaskStatus.WaitingForActivation:
                    WaitAntecedent(cancellationToken, milliseconds, start);
                    ExecutingTaskScheduler.InternalTryExecuteTaskInline(this, true);
                    break;

                case TaskStatus.Created:
                case TaskStatus.WaitingToRun:
                case TaskStatus.Running:
                case TaskStatus.WaitingForChildrenToComplete:
                    var waitHandle = _waitHandle.Value;
                    waitHandle?.Wait
                    (
                        TimeSpan.FromMilliseconds
                        (
                            milliseconds - ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start)
                        ),
                        cancellationToken
                    );
                    break;

                case TaskStatus.RanToCompletion:
                    return(true);

                case TaskStatus.Canceled:
                    ThrowIfExceptional(true);
                    return(true);

                case TaskStatus.Faulted:
                    ThrowIfExceptional(true);
                    return(true);

                default:
                    // Should not happen
                    continue;
                }
            } while (ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start) < milliseconds);
            switch (Status)
            {
            case TaskStatus.RanToCompletion:
                return(true);

            case TaskStatus.Canceled:
                ThrowIfExceptional(true);
                return(true);

            case TaskStatus.Faulted:
                ThrowIfExceptional(true);
                return(true);

            default:
                return(false);
            }
        }
コード例 #10
0
 public Task(Func <object, TResult> function, object state, CancellationToken token, TaskCreationOptions options)
     : base(null, state, token, options)
 {
     this.function = function;
     this.state    = state;
 }
コード例 #11
0
ファイル: Task.net35.cs プロジェクト: NN---/Theraot
 public Task(Action action, CancellationToken cancellationToken)
     : this(action, null, null, cancellationToken, TaskCreationOptions.None, InternalTaskOptions.None, TaskScheduler.Default)
 {
     // Empty
 }
コード例 #12
0
 public Task(Func <object, TResult> function, object state, CancellationToken token)
     : this(function, state, token, TaskCreationOptions.None)
 {
 }
コード例 #13
0
 public Task(Func <TResult> function, CancellationToken token, TaskCreationOptions options)
     : this((o) => function(), null, token, options)
 {
 }
コード例 #14
0
        public Task <TNewResult> ContinueWith <TNewResult> (Func <Task <TResult>, TNewResult> a, CancellationToken token,
                                                            TaskContinuationOptions options,
                                                            TaskScheduler scheduler)
        {
            Task <TNewResult> t = new Task <TNewResult> ((o) => a((Task <TResult>)o), this, token, GetCreationOptions(options));

            ContinueWithCore(t, options, scheduler);

            return(t);
        }
コード例 #15
0
 public Task <TNewResult> ContinueWith <TNewResult> (Func <Task <TResult>, TNewResult> a, CancellationToken token)
 {
     return(ContinueWith <TNewResult> (a, token, TaskContinuationOptions.None, TaskScheduler.Current));
 }
コード例 #16
0
 public Task ContinueWith(Action <Task <TResult> > a, CancellationToken token)
 {
     return(ContinueWith(a, token, TaskContinuationOptions.None, TaskScheduler.Current));
 }