看了上一篇C# Task 是什么?返回值如何实现? Wait如何实现 我们提到FinishContinuations方法中会调用TaskContinuation实例,那么我们的ContinueWith就应该非常简单,只需要把TASK放到TaskContinuation结合中就可以了,ContinueWith可以是 Action<Task<TResult>>也可以是 Func<Task<TResult>,TNewResult> ,其中Task<TResult>的实现如下:
public class Task<TResult> : Task{ //Creates a continuation that executes when the target Task{TResult}" completes public Task ContinueWith(Action<Task<TResult>> continuationAction) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return ContinueWith(continuationAction, TaskScheduler.Current, default(CancellationToken), TaskContinuationOptions.None, ref stackMark); } internal Task ContinueWith(Action<Task<TResult>> continuationAction, TaskScheduler scheduler, CancellationToken cancellationToken,TaskContinuationOptions continuationOptions, ref StackCrawlMark stackMark) { if (continuationAction == null) { throw new ArgumentNullException("continuationAction"); } if (scheduler == null) { throw new ArgumentNullException("scheduler"); } TaskCreationOptions creationOptions; InternalTaskOptions internalOptions; CreationOptionsFromContinuationOptions(continuationOptions,out creationOptions,out internalOptions); Task continuationTask = new ContinuationTaskFromResultTask<TResult>(this, continuationAction, null, creationOptions, internalOptions,ref stackMark); ContinueWithCore(continuationTask, scheduler, cancellationToken, continuationOptions); return continuationTask; } public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, Object, TNewResult> continuationFunction, Object state) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return ContinueWith<TNewResult>(continuationFunction, state, TaskScheduler.Current, default(CancellationToken), TaskContinuationOptions.None, ref stackMark); } // Same as the above overload, just with a stack mark. internal Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, Object, TNewResult> continuationFunction, Object state,TaskScheduler scheduler, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, ref StackCrawlMark stackMark) { if (continuationFunction == null) { throw new ArgumentNullException("continuationFunction"); } if (scheduler == null) { throw new ArgumentNullException("scheduler"); } TaskCreationOptions creationOptions; InternalTaskOptions internalOptions; CreationOptionsFromContinuationOptions(continuationOptions,out creationOptions,out internalOptions); Task<TNewResult> continuationFuture = new ContinuationResultTaskFromResultTask<TResult,TNewResult>(this, continuationFunction, state,creationOptions, internalOptions,ref stackMark); ContinueWithCore(continuationFuture, scheduler, cancellationToken, continuationOptions); return continuationFuture; } }
ContinueWith的核心是调用Task的ContinueWithCore方法,这里把我们的Action或Fun包装成子的Task,比如这里的ContinuationResultTaskFromResultTask实现【很是标准】如下:
internal sealed class ContinuationResultTaskFromResultTask<TAntecedentResult, TResult> : Task<TResult> { private Task<TAntecedentResult> m_antecedent; public ContinuationResultTaskFromResultTask( Task<TAntecedentResult> antecedent, Delegate function, object state, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, ref StackCrawlMark stackMark) : base(function, state, Task.InternalCurrentIfAttached(creationOptions), default(CancellationToken), creationOptions, internalOptions, null) { Contract.Requires(function is Func<Task<TAntecedentResult>, TResult> || function is Func<Task<TAntecedentResult>, object, TResult>, "Invalid delegate type in ContinuationResultTaskFromResultTask