Skip to content

Instantly share code, notes, and snippets.

@elusive
Created January 4, 2021 14:54
Show Gist options
  • Save elusive/5892e65ba878dc0c281bb86b04b846b1 to your computer and use it in GitHub Desktop.
Save elusive/5892e65ba878dc0c281bb86b04b846b1 to your computer and use it in GitHub Desktop.
Task extension methods for executing in series/sequence.
public static class TaskExtensions
{
/// <summary>
/// Executes the next task after the completion of the first.
/// </summary>
/// <param name="first">Currently executing task.</param>
/// <param name="next">Function returning the task to execute next.</param>
/// <returns>The next task instance.</returns>
public static Task Then(this Task first, Func<Task> next)
{
if (first == null) throw new ArgumentNullException(nameof(first));
if (next == null) throw new ArgumentNullException(nameof(next));
var tcs = new TaskCompletionSource<object>();
first.ContinueWith(delegate
{
if (first.IsFaulted && first.Exception != null)
tcs.TrySetException(first.Exception.InnerExceptions);
else if (first.IsCanceled) tcs.TrySetCanceled();
else
try
{
var t = next();
if (t == null) tcs.TrySetCanceled();
else
t.ContinueWith(delegate
{
if (t.IsFaulted && t.Exception != null)
tcs.TrySetException(t.Exception.InnerExceptions);
else if (t.IsCanceled) tcs.TrySetCanceled();
else tcs.TrySetResult(null);
}, TaskContinuationOptions.ExecuteSynchronously);
}
catch (Exception exc)
{
tcs.TrySetException(exc);
}
}, TaskContinuationOptions.ExecuteSynchronously);
return tcs.Task;
}
/// <summary>
/// Executes the params array of tasks in sequence.
/// </summary>
/// <param name="actions">
/// Destructured array of functions
/// that return the tasks to execute.
/// </param>
/// <returns>The final task instance.</returns>
public static Task Sequence(params Func<Task>[] actions)
{
Task last = null;
foreach (var action in actions)
last = last == null ? Task.Factory.StartNew(action).Unwrap() : last.Then(action);
return last;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment