为Task扩展Linq
This commit is contained in:
parent
bd9142b451
commit
040f6d9759
|
@ -1,4 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Sanchime.Functional.Core.Products;
|
||||
namespace Sanchime.Functional.Core.Extensions;
|
||||
|
||||
public static class TaskExtension
|
||||
|
@ -9,7 +12,9 @@ public static class TaskExtension
|
|||
#region 函子
|
||||
|
||||
public static Task<R> Map<T, R>(this Task<T> @this, Func<Exception, R> Faulted, Func<T, R> Completed)
|
||||
=> @this.ContinueWith(val => val.Status == TaskStatus.Faulted ? Faulted(val.Exception!) : Completed(val.Result));
|
||||
=> @this.ContinueWith(val => val.Status == TaskStatus.Faulted
|
||||
? Faulted(val.Exception!)
|
||||
: Completed(val.Result));
|
||||
|
||||
public static async Task<R> Map<T, R>(this Task<T> @this, Func<T, R> mapping)
|
||||
=> mapping(await @this.ConfigureAwait(false));
|
||||
|
@ -22,16 +27,102 @@ public static class TaskExtension
|
|||
|
||||
public static Task<Func<T2, R>> Map<T1, T2, R>(this Task<T1> @this, Func<T1, T2, R> mapping)
|
||||
=> @this.Map(mapping.Curry());
|
||||
#endregion
|
||||
|
||||
#region 单子
|
||||
public static async Task<R> Bind<T, R>(this Task<T> @this, Func<T, Task<R>> binding)
|
||||
=> await binding(await @this.ConfigureAwait(false)).ConfigureAwait(false);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 应用子
|
||||
public static async Task<R> Apply<T, R>(this Task<Func<T, R>> @this, Task<T> task)
|
||||
=> (await @this.ConfigureAwait(false))(await task.ConfigureAwait(false));
|
||||
|
||||
public static Task<Func<T2, R>> Apply<T1, T2, R>(this Task<Func<T1, T2, R>> @this, Task<T1> task)
|
||||
=> @this.Map(CurryingExtension.Curry).Apply(task);
|
||||
|
||||
#endregion
|
||||
|
||||
public static Task<T> OrElse<T>(this Task<T> @this, Func<Task<T>> fallback)
|
||||
=> @this.ContinueWith(task => task.Status == TaskStatus.Faulted
|
||||
? fallback()
|
||||
: Task.FromResult(task.Result))
|
||||
.Unwrap();
|
||||
|
||||
public static Task<T> Recover<T>(this Task<T> @this, Func<Exception, T> fallback)
|
||||
=> @this.ContinueWith(task => task.Status == TaskStatus.Faulted
|
||||
? fallback(task.Exception!)
|
||||
: task.Result);
|
||||
|
||||
public static Task<T> RecoverWith<T>(this Task<T> @this, Func<Exception, Task<T>> fallback)
|
||||
=> @this.ContinueWith(task => task.Status == TaskStatus.Faulted
|
||||
? fallback(task.Exception!)
|
||||
: Task.FromResult(task.Result))
|
||||
.Unwrap();
|
||||
|
||||
public static Task<Unit> ForEach<T>(this Task<T> @this, Action<T> continuaction)
|
||||
=> @this.ContinueWith(task => continuaction.ToFunc()(task.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
|
||||
|
||||
#region Linq式
|
||||
|
||||
public static async Task<RR> SelectMany<T, R, RR>(this Task<T> source, Func<T, Task<R>> binding, Func<T, R, RR> project)
|
||||
{
|
||||
var task = await source;
|
||||
var result = await binding(task);
|
||||
return project(task, result);
|
||||
}
|
||||
|
||||
public static async Task<RR> SelectMany<T, R, RR>(this Task<T> source, Func<T, ValueTask<R>> binding, Func<T, R, RR> project)
|
||||
{
|
||||
var task = await source;
|
||||
var result = await binding(task);
|
||||
return project(task, result);
|
||||
}
|
||||
|
||||
public static async Task<RR> SelectMany<T, R, RR>(this Task<T> source, Func<Unit, Task<R>> binding, Func<Unit, R, RR> project)
|
||||
{
|
||||
await source;
|
||||
var result = await binding(Unit.Value);
|
||||
return project(Unit.Value, result);
|
||||
}
|
||||
|
||||
public static async Task<R> SelectMany<T, R, RR>(this Task<T> source, Func<T, Task<R>> binding)
|
||||
=> await binding(await source.ConfigureAwait(false)).ConfigureAwait(false);
|
||||
|
||||
public static async Task<R> Select<T, R>(this Task<T> source, Func<T, R> mapping)
|
||||
=> mapping(await source);
|
||||
|
||||
public static async Task<T> Where<T>(this Task<T> source, Func<T, bool> predicate)
|
||||
{
|
||||
var task = await source;
|
||||
if (!predicate(task))
|
||||
{
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
public static async Task<V> Join<T, U, K, V>(this Task<T> source, Task<U> inner, Func<T, K> outerKeySelector, Func<U, K> innerKeySelector, Func<T, U, V> resultSelector)
|
||||
{
|
||||
await Task.WhenAll(source, inner);
|
||||
|
||||
if (!EqualityComparer<K>.Default.Equals(outerKeySelector(source.Result), innerKeySelector(inner.Result)))
|
||||
{
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
|
||||
return resultSelector(source.Result, inner.Result);
|
||||
}
|
||||
|
||||
public static async Task<V> GroupJoin<T, U, K, V>(this Task<T> source, Task<U> inner, Func<T, K> outerKeySelector, Func<U, K> innerKeySelector, Func<T, Task<U>, V> resultSelector)
|
||||
{
|
||||
var task = await source;
|
||||
return resultSelector(task,
|
||||
inner.Where(u => EqualityComparer<K>.Default.Equals(
|
||||
outerKeySelector(task), innerKeySelector(u))));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue