RLC.TaskChaining
0.1.0
See the version list below for details.
dotnet add package RLC.TaskChaining --version 0.1.0
NuGet\Install-Package RLC.TaskChaining -Version 0.1.0
<PackageReference Include="RLC.TaskChaining" Version="0.1.0" />
<PackageVersion Include="RLC.TaskChaining" Version="0.1.0" />
<PackageReference Include="RLC.TaskChaining" />
paket add RLC.TaskChaining --version 0.1.0
#r "nuget: RLC.TaskChaining, 0.1.0"
#:package RLC.TaskChaining@0.1.0
#addin nuget:?package=RLC.TaskChaining&version=0.1.0
#tool nuget:?package=RLC.TaskChaining&version=0.1.0
RLC.TaskChaining
Monadic-style chaining for C# Tasks.
Rationale
Asynchronous code (particularly in C#) typically relies on using the async/await feature introduced in C# 5.0. This has a lot of benefits, but it unfortunately tends to push code into an imperative style. This library aims to make writing asychronous functional code easier, cleaner, and less error-prone using extensions to System.Threading.Tasks.
Installation
Install RLC.TaskChaining as a NuGet package via an IDE package manager or using the command-line instructions at nuget.org.
API
Chaining
Then
Once a Task<T> has been created, successive operations can be chained using the Then method.
HttpClient client; // Assuming this is coming from an HttpClientFactory or injected or whatever
Task.FromResult("https://www.google.com") // Task<string>
.Then(client.GetAsync) // Task<HttpResponseMessage>
.Then(response => response.StatusCode); // Task<System.Net.HttpStatusCode>
Catch
When a Task<T> enters a faulted state, the Catch method can be used to return the Task<T> to a non-faulted state.
HttpClient client; // Assuming this is coming from an HttpClientFactory or injected or whatever
Task.FromResult("not-a-url") // Task<string>
.Then(client.GetAsync) // Task<HttpResponseMessage> but FAULTED
.Catch(exception => exception.Message) // Task<string> and NOT FAULTED
.Then(message => message.Length) // Task<int>
Note that it's entirely possible for a Catch method to cause the Task<T> to remain in a faulted state, e.g. if you only wanted to recover into a non-faulted state if a particular exception type occurred.
HttpClient client; // Assuming this is coming from an HttpClientFactory or injected or whatever
Task.FromResult("not-a-url") // Task<string>
.Then(client.GetAsync) // Task<HttpResponseMessage> but FAULTED
.Catch(exception => exception is NullReferenceException
? exception.Message
: Task.FromException(exception)) // Task<string> but STILL FAULTED if anything other than NullReferenceException occurred
.Then(message => message.Length) // Task<int>
IfFulfilled/IfRejected/Tap
The IfFulfilled and IfRejected methods can be used to perform side effects such as logging when the Promise<T> is in the fulfilled or faulted state, respectively.
HttpClient client; // Assuming this is coming from an HttpClientFactory or injected or whatever
Promise<string>.Resolve("https://www.google.com/")
.Then(client.GetAsync)
.IfFulfilled(response => _logger.LogDebug("Got response {Response}", response)
.Then(response => response.StatusCode);
HttpClient client; // Assuming this is coming from an HttpClientFactory or injected or whatever
Promise<string>.Resolve("not-a-url")
.Then(client.GetAsync)
.IfRejected(exception => _logger.LogException(exception, "Failed to get URL")
.Catch(exception => exception.Message)
.Then(message => message.Length);
The Tap method takes both an onFulfilled and onRejected Action in the event that you want to perform some side effect on both sides of the Promise at a single time.
HttpClient client; // Assuming this is coming from an HttpClientFactory or injected or whatever
Promise<string>.Resolve(someExternalUrl)
.Then(client.GetAsync)
.Tap(
response => _logger.LogDebug("Got response {Response}", response),
exception => _logger.LogException(exception, "Failed to get URL")
)
Static Methods
There are some convenience methods on TaskExtras that are useful when transitioning between the fulfilled and faulted states.
RejectIf
RejectIf can be used to transition into a faulted state based on some Predicate<T>.
Task.FromResult(1)
.Then(TaskExtras.RejectIf(
value => value % 2 == 0,
value => new Exception($"{nameof(value)} was not even")
));
ResolveIf
ResolveIf can be used to transition from a faulted state to a fulfilled state based on some Predicate<Exception>.
Task.FromException<int>(new ArgumentException())
.Catch(TaskExtras.ResolveIf(
exception => exception is ArgumentException,
exception => exception.Message.Length
))
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net6.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.20.0 | 890 | 7/8/2025 |
| 2.19.2 | 2,074 | 3/27/2025 |
| 2.19.0 | 308 | 3/6/2025 |
| 2.18.5 | 1,435 | 11/25/2024 |
| 2.18.4 | 189 | 11/22/2024 |
| 2.18.3 | 184 | 11/22/2024 |
| 2.18.2 | 195 | 11/22/2024 |
| 2.18.1 | 1,127 | 7/26/2024 |
| 2.16.1 | 2,106 | 4/20/2024 |
| 2.16.0 | 974 | 12/18/2023 |
| 2.15.0 | 2,312 | 11/1/2023 |
| 2.14.0 | 2,166 | 5/14/2023 |
| 2.13.0 | 591 | 5/12/2023 |
| 2.12.0 | 554 | 5/12/2023 |
| 2.11.0 | 9,416 | 3/12/2023 |
| 2.10.0 | 872 | 12/29/2022 |
| 2.9.0 | 916 | 9/22/2022 |
| 2.8.0 | 849 | 9/21/2022 |
| 2.7.0 | 1,137 | 6/18/2022 |
| 2.6.0 | 895 | 6/17/2022 |
| 2.5.0 | 879 | 6/16/2022 |
| 2.4.0 | 947 | 6/10/2022 |
| 2.3.0 | 891 | 6/9/2022 |
| 2.2.0 | 866 | 5/20/2022 |
| 2.1.2 | 890 | 5/17/2022 |
| 2.1.1 | 916 | 5/13/2022 |
| 2.1.0 | 854 | 5/13/2022 |
| 2.0.0 | 866 | 5/1/2022 |
| 1.0.0 | 880 | 4/26/2022 |
| 0.3.1 | 836 | 4/26/2022 |
| 0.3.0 | 852 | 4/26/2022 |
| 0.2.0 | 903 | 4/24/2022 |
| 0.1.1 | 879 | 4/18/2022 |
| 0.1.0 | 942 | 4/18/2022 |