Created
February 19, 2019 07:32
-
-
Save RyuaNerin/677effde0a265cbaee2ced00e26d3144 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Threading.Tasks; | |
namespace TaskExtension | |
{ | |
internal static class TaskHelper | |
{ | |
private struct VoidResult | |
{ | |
} | |
public static void Finally(this Task task, Action action) | |
{ | |
task.ContinueWith(eTask => | |
{ | |
action(); | |
}); | |
} | |
public static Task OnSuccess (this Task task, Action action) | |
{ | |
var tcs = new TaskCompletionSource<VoidResult>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
tcs.SetException(eTask.Exception); | |
else if (eTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
action(); | |
}); | |
return tcs.Task; | |
} | |
public static Task OnSuccess<TTask> (this Task<TTask> task, Action<TTask> action) | |
{ | |
var tcs = new TaskCompletionSource<TTask>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
tcs.SetException(eTask.Exception); | |
else if (eTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
action(eTask.Result); | |
}); | |
return tcs.Task; | |
} | |
public static Task OnFaulted (this Task task, Action<Exception> exceptionAction) | |
{ | |
var tcs = new TaskCompletionSource<VoidResult>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
{ | |
var innerException = eTask.Exception.Flatten().InnerExceptions.FirstOrDefault(); | |
exceptionAction?.Invoke(innerException ?? eTask.Exception); | |
} | |
else if (eTask.IsCanceled) | |
tcs.SetCanceled(); | |
else | |
tcs.TrySetResult(default(VoidResult)); | |
}); | |
return tcs.Task; | |
} | |
public static Task<TTask> OnFaulted<TTask> (this Task<TTask> task, Action<Exception> exceptionAction) | |
{ | |
var tcs = new TaskCompletionSource<TTask>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
{ | |
var innerException = eTask.Exception.Flatten().InnerExceptions.FirstOrDefault(); | |
exceptionAction?.Invoke(innerException ?? eTask.Exception); | |
} | |
else if (eTask.IsCanceled) | |
tcs.SetCanceled(); | |
else | |
tcs.TrySetResult(eTask.Result); | |
}); | |
return tcs.Task; | |
} | |
public static Task OnCanceled (this Task task, Action action) | |
{ | |
var tcs = new TaskCompletionSource<VoidResult>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
tcs.SetException(eTask.Exception); | |
else if (eTask.IsCanceled) | |
action(); | |
else | |
tcs.SetResult(default(VoidResult)); | |
}); | |
return tcs.Task; | |
} | |
public static Task<TTask> OnCanceled<TTask> (this Task<TTask> task, Action action) | |
{ | |
var tcs = new TaskCompletionSource<TTask>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
tcs.SetException(eTask.Exception); | |
else if (eTask.IsCanceled) | |
action(); | |
else | |
tcs.SetResult(eTask.Result); | |
}); | |
return tcs.Task; | |
} | |
public static Task Then (this Task task, Action<Task > next) | |
{ | |
var tcs = new TaskCompletionSource<VoidResult>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
tcs.TrySetException(eTask.Exception); | |
else if (eTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
{ | |
try | |
{ | |
next(eTask); | |
tcs.TrySetResult(default(VoidResult)); | |
} | |
catch (Exception ex) | |
{ | |
tcs.TrySetException(ex); | |
} | |
} | |
}); | |
return tcs.Task; | |
} | |
public static Task Then (this Task task, Func <Task, Task > next) | |
{ | |
var tcs = new TaskCompletionSource<VoidResult>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
tcs.TrySetException(eTask.Exception); | |
else if (eTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
{ | |
try | |
{ | |
next(eTask).ContinueWith(nTask => | |
{ | |
if (nTask.IsFaulted) | |
tcs.TrySetException(nTask.Exception); | |
else if (nTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
tcs.TrySetResult(default(VoidResult)); | |
}); | |
} | |
catch (Exception ex) | |
{ | |
tcs.TrySetException(ex); | |
} | |
} | |
}); | |
return tcs.Task; | |
} | |
public static Task Then<TTask> (this Task<TTask> task, Action<Task<TTask> > next) | |
{ | |
var tcs = new TaskCompletionSource<VoidResult>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
tcs.TrySetException(eTask.Exception); | |
else if (eTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
{ | |
try | |
{ | |
next(eTask); | |
tcs.TrySetResult(default(VoidResult)); | |
} | |
catch (Exception ex) | |
{ | |
tcs.TrySetException(ex); | |
} | |
} | |
}); | |
return tcs.Task; | |
} | |
public static Task Then<TTask> (this Task<TTask> task, Func <Task<TTask>, Task > next) | |
{ | |
var tcs = new TaskCompletionSource<VoidResult>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
tcs.TrySetException(eTask.Exception); | |
else if (eTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
{ | |
try | |
{ | |
next(eTask).ContinueWith(nTask => | |
{ | |
if (nTask.IsFaulted) | |
tcs.TrySetException(nTask.Exception); | |
else if (nTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
tcs.TrySetResult(default(VoidResult)); | |
}); | |
} | |
catch (Exception ex) | |
{ | |
tcs.TrySetException(ex); | |
} | |
} | |
}); | |
return tcs.Task; | |
} | |
public static Task<TFunc> Then<TFunc> (this Task task, Func <Task, TFunc > next) | |
{ | |
var tcs = new TaskCompletionSource<TFunc>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
tcs.TrySetException(eTask.Exception); | |
else if (eTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
{ | |
try | |
{ | |
tcs.TrySetResult(next(eTask)); | |
} | |
catch (Exception ex) | |
{ | |
tcs.TrySetException(ex); | |
} | |
} | |
}); | |
return tcs.Task; | |
} | |
public static Task<TFunc> Then<TFunc> (this Task task, Func <Task , Task<TFunc>> next) | |
{ | |
var tcs = new TaskCompletionSource<TFunc>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
tcs.TrySetException(eTask.Exception); | |
else if (eTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
{ | |
try | |
{ | |
next(eTask).ContinueWith(nTask => | |
{ | |
if (nTask.IsFaulted) | |
tcs.TrySetException(nTask.Exception); | |
else if (nTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
{ | |
try | |
{ | |
tcs.TrySetResult(nTask.Result); | |
} | |
catch (Exception ex) | |
{ | |
tcs.TrySetException(ex); | |
} | |
} | |
}); | |
} | |
catch (Exception ex) | |
{ | |
tcs.TrySetException(ex); | |
} | |
} | |
}); | |
return tcs.Task; | |
} | |
public static Task<TFunc> Then<TTask, TFunc> (this Task<TTask> task, Func <Task<TTask>, TFunc > next) | |
{ | |
var tcs = new TaskCompletionSource<TFunc>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
tcs.TrySetException(eTask.Exception); | |
else if (eTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
{ | |
try | |
{ | |
tcs.TrySetResult(next(eTask)); | |
} | |
catch (Exception ex) | |
{ | |
tcs.TrySetException(ex); | |
} | |
} | |
}); | |
return tcs.Task; | |
} | |
public static Task<TFunc> Then<TTask, TFunc> (this Task<TTask> task, Func <Task<TTask>, Task<TFunc>> next) | |
{ | |
var tcs = new TaskCompletionSource<TFunc>(); | |
task.ContinueWith(eTask => | |
{ | |
if (eTask.IsFaulted) | |
tcs.TrySetException(eTask.Exception); | |
else if (eTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
{ | |
try | |
{ | |
next(eTask).ContinueWith(nTask => | |
{ | |
if (nTask.IsFaulted) | |
tcs.TrySetException(nTask.Exception); | |
else if (nTask.IsCanceled) | |
tcs.TrySetCanceled(); | |
else | |
{ | |
try | |
{ | |
tcs.TrySetResult(nTask.Result); | |
} | |
catch (Exception ex) | |
{ | |
tcs.TrySetException(ex); | |
} | |
} | |
}); | |
} | |
catch (Exception ex) | |
{ | |
tcs.TrySetException(ex); | |
} | |
} | |
}); | |
return tcs.Task; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment