Skip to content

Commit e6a6793

Browse files
committed
Added TupleTaskExtensions + TupleValueTaskExtensions
1 parent bb1cadb commit e6a6793

File tree

6 files changed

+350
-2
lines changed

6 files changed

+350
-2
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// <copyright file="TupleTaskExtensions.cs" company="Zircon Technology">
2+
// This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution.
3+
// </copyright>
4+
5+
using System.Runtime.CompilerServices;
6+
using ZirconNet.Core.Helpers;
7+
8+
namespace ZirconNet.Core.Extensions;
9+
10+
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1414:Tuple types in signatures should have element names", Justification = "Wont be used.")]
11+
public static class TupleTaskExtensions
12+
{
13+
public static TaskAwaiter<(T1, T2)> GetAwaiter<T1, T2>(this (Task<T1>, Task<T2>) taskTuple)
14+
{
15+
async Task<(T1, T2)> CombineTasks()
16+
{
17+
var (task1, task2) = taskTuple;
18+
await TaskHelper.WhenAll(task1, task2);
19+
return (task1.Result, task2.Result);
20+
}
21+
22+
return CombineTasks().GetAwaiter();
23+
}
24+
25+
public static TaskAwaiter<(T1, T2, T3)> GetAwaiter<T1, T2, T3>(this (Task<T1>, Task<T2>, Task<T3>) taskTuple)
26+
{
27+
async Task<(T1, T2, T3)> CombineTasks()
28+
{
29+
var (task1, task2, task3) = taskTuple;
30+
await TaskHelper.WhenAll(task1, task2, task3);
31+
return (task1.Result, task2.Result, task3.Result);
32+
}
33+
34+
return CombineTasks().GetAwaiter();
35+
}
36+
37+
public static TaskAwaiter<(T1, T2, T3, T4)> GetAwaiter<T1, T2, T3, T4>(this (Task<T1>, Task<T2>, Task<T3>, Task<T4>) taskTuple)
38+
{
39+
async Task<(T1, T2, T3, T4)> CombineTasks()
40+
{
41+
var (task1, task2, task3, task4) = taskTuple;
42+
await TaskHelper.WhenAll(task1, task2, task3, task4);
43+
return (task1.Result, task2.Result, task3.Result, task4.Result);
44+
}
45+
46+
return CombineTasks().GetAwaiter();
47+
}
48+
49+
public static TaskAwaiter<(T1, T2, T3, T4, T5)> GetAwaiter<T1, T2, T3, T4, T5>(this (Task<T1>, Task<T2>, Task<T3>, Task<T4>, Task<T5>) taskTuple)
50+
{
51+
async Task<(T1, T2, T3, T4, T5)> CombineTasks()
52+
{
53+
var (task1, task2, task3, task4, task5) = taskTuple;
54+
await TaskHelper.WhenAll(task1, task2, task3, task4, task5);
55+
return (task1.Result, task2.Result, task3.Result, task4.Result, task5.Result);
56+
}
57+
58+
return CombineTasks().GetAwaiter();
59+
}
60+
61+
public static TaskAwaiter<(T1, T2, T3, T4, T5, T6)> GetAwaiter<T1, T2, T3, T4, T5, T6>(this (Task<T1>, Task<T2>, Task<T3>, Task<T4>, Task<T5>, Task<T6>) taskTuple)
62+
{
63+
async Task<(T1, T2, T3, T4, T5, T6)> CombineTasks()
64+
{
65+
var (task1, task2, task3, task4, task5, task6) = taskTuple;
66+
await TaskHelper.WhenAll(task1, task2, task3, task4, task5, task6);
67+
return (task1.Result, task2.Result, task3.Result, task4.Result, task5.Result, task6.Result);
68+
}
69+
70+
return CombineTasks().GetAwaiter();
71+
}
72+
73+
public static TaskAwaiter<(T1, T2, T3, T4, T5, T6, T7)> GetAwaiter<T1, T2, T3, T4, T5, T6, T7>(this (Task<T1>, Task<T2>, Task<T3>, Task<T4>, Task<T5>, Task<T6>, Task<T7>) taskTuple)
74+
{
75+
async Task<(T1, T2, T3, T4, T5, T6, T7)> CombineTasks()
76+
{
77+
var (task1, task2, task3, task4, task5, task6, task7) = taskTuple;
78+
await TaskHelper.WhenAll(task1, task2, task3, task4, task5, task6, task7);
79+
return (task1.Result, task2.Result, task3.Result, task4.Result, task5.Result, task6.Result, task7.Result);
80+
}
81+
82+
return CombineTasks().GetAwaiter();
83+
}
84+
85+
public static TaskAwaiter<(T1, T2, T3, T4, T5, T6, T7, T8)> GetAwaiter<T1, T2, T3, T4, T5, T6, T7, T8>(this (Task<T1>, Task<T2>, Task<T3>, Task<T4>, Task<T5>, Task<T6>, Task<T7>, Task<T8>) taskTuple)
86+
{
87+
async Task<(T1, T2, T3, T4, T5, T6, T7, T8)> CombineTasks()
88+
{
89+
var (task1, task2, task3, task4, task5, task6, task7, task8) = taskTuple;
90+
await TaskHelper.WhenAll(task1, task2, task3, task4, task5, task6, task7, task8);
91+
return (task1.Result, task2.Result, task3.Result, task4.Result, task5.Result, task6.Result, task7.Result, task8.Result);
92+
}
93+
94+
return CombineTasks().GetAwaiter();
95+
}
96+
97+
public static TaskAwaiter GetAwaiter(this (Task, Task) taskTuple)
98+
{
99+
return TaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2).GetAwaiter();
100+
}
101+
102+
public static TaskAwaiter GetAwaiter(this (Task, Task, Task) taskTuple)
103+
{
104+
return TaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3).GetAwaiter();
105+
}
106+
107+
public static TaskAwaiter GetAwaiter(this (Task, Task, Task, Task) taskTuple)
108+
{
109+
return TaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4).GetAwaiter();
110+
}
111+
112+
public static TaskAwaiter GetAwaiter(this (Task, Task, Task, Task, Task) taskTuple)
113+
{
114+
return TaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4, taskTuple.Item5).GetAwaiter();
115+
}
116+
117+
public static TaskAwaiter GetAwaiter(this (Task, Task, Task, Task, Task, Task) taskTuple)
118+
{
119+
return TaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4, taskTuple.Item5, taskTuple.Item6).GetAwaiter();
120+
}
121+
122+
public static TaskAwaiter GetAwaiter(this (Task, Task, Task, Task, Task, Task, Task) taskTuple)
123+
{
124+
return TaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4, taskTuple.Item5, taskTuple.Item6, taskTuple.Item7).GetAwaiter();
125+
}
126+
127+
public static TaskAwaiter GetAwaiter(this (Task, Task, Task, Task, Task, Task, Task, Task) taskTuple)
128+
{
129+
return TaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4, taskTuple.Item5, taskTuple.Item6, taskTuple.Item7, taskTuple.Item8).GetAwaiter();
130+
}
131+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// <copyright file="TupleValueTaskExtensions.cs" company="Zircon Technology">
2+
// This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution.
3+
// </copyright>
4+
5+
using System.Runtime.CompilerServices;
6+
using ZirconNet.Core.Helpers;
7+
8+
namespace ZirconNet.Core.Extensions;
9+
10+
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1414:Tuple types in signatures should have element names", Justification = "Wont be used.")]
11+
public static class TupleValueTaskExtensions
12+
{
13+
public static ValueTaskAwaiter<T[]> GetAwaiter<T>(this (ValueTask<T>, ValueTask<T>) taskTuple)
14+
{
15+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2).GetAwaiter();
16+
}
17+
18+
public static ValueTaskAwaiter<T[]> GetAwaiter<T>(this (ValueTask<T>, ValueTask<T>, ValueTask<T>) taskTuple)
19+
{
20+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3).GetAwaiter();
21+
}
22+
23+
public static ValueTaskAwaiter<T[]> GetAwaiter<T>(this (ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>) taskTuple)
24+
{
25+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4).GetAwaiter();
26+
}
27+
28+
public static ValueTaskAwaiter<T[]> GetAwaiter<T>(this (ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>) taskTuple)
29+
{
30+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4, taskTuple.Item5).GetAwaiter();
31+
}
32+
33+
public static ValueTaskAwaiter<T[]> GetAwaiter<T>(this (ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>) taskTuple)
34+
{
35+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4, taskTuple.Item5, taskTuple.Item6).GetAwaiter();
36+
}
37+
38+
public static ValueTaskAwaiter<T[]> GetAwaiter<T>(this (ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>) taskTuple)
39+
{
40+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4, taskTuple.Item5, taskTuple.Item6, taskTuple.Item7).GetAwaiter();
41+
}
42+
43+
public static ValueTaskAwaiter<T[]> GetAwaiter<T>(this (ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>, ValueTask<T>) taskTuple)
44+
{
45+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4, taskTuple.Item5, taskTuple.Item6, taskTuple.Item7, taskTuple.Item8).GetAwaiter();
46+
}
47+
48+
public static ValueTaskAwaiter GetAwaiter(this (ValueTask, ValueTask) taskTuple)
49+
{
50+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2).GetAwaiter();
51+
}
52+
53+
public static ValueTaskAwaiter GetAwaiter(this (ValueTask, ValueTask, ValueTask) taskTuple)
54+
{
55+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3).GetAwaiter();
56+
}
57+
58+
public static ValueTaskAwaiter GetAwaiter(this (ValueTask, ValueTask, ValueTask, ValueTask) taskTuple)
59+
{
60+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4).GetAwaiter();
61+
}
62+
63+
public static ValueTaskAwaiter GetAwaiter(this (ValueTask, ValueTask, ValueTask, ValueTask, ValueTask) taskTuple)
64+
{
65+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4, taskTuple.Item5).GetAwaiter();
66+
}
67+
68+
public static ValueTaskAwaiter GetAwaiter(this (ValueTask, ValueTask, ValueTask, ValueTask, ValueTask, ValueTask) taskTuple)
69+
{
70+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4, taskTuple.Item5, taskTuple.Item6).GetAwaiter();
71+
}
72+
73+
public static ValueTaskAwaiter GetAwaiter(this (ValueTask, ValueTask, ValueTask, ValueTask, ValueTask, ValueTask, ValueTask) taskTuple)
74+
{
75+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4, taskTuple.Item5, taskTuple.Item6, taskTuple.Item7).GetAwaiter();
76+
}
77+
78+
public static ValueTaskAwaiter GetAwaiter(this (ValueTask, ValueTask, ValueTask, ValueTask, ValueTask, ValueTask, ValueTask, ValueTask) taskTuple)
79+
{
80+
return ValueTaskHelper.WhenAll(taskTuple.Item1, taskTuple.Item2, taskTuple.Item3, taskTuple.Item4, taskTuple.Item5, taskTuple.Item6, taskTuple.Item7, taskTuple.Item8).GetAwaiter();
81+
}
82+
}

src/ZirconNet.Core/Extensions/ValueTaskExtensions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// <copyright file="ValueTaskExtensions.cs" company="Zircon Technology">
22
// This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution.
33
// </copyright>
4-
54
namespace ZirconNet.Core.Extensions;
65

76
public static class ValueTaskExtensions
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// <copyright file="TaskHelper.cs" company="Zircon Technology">
2+
// This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution.
3+
// </copyright>
4+
5+
namespace ZirconNet.Core.Helpers;
6+
7+
public static class TaskHelper
8+
{
9+
public static async Task<T[]> WhenAll<T>(params Task<T>[] tasks)
10+
{
11+
var allTasks = Task.WhenAll(tasks);
12+
13+
try
14+
{
15+
return await allTasks;
16+
}
17+
catch (Exception)
18+
{
19+
// ignore
20+
}
21+
22+
throw allTasks.Exception ?? throw new();
23+
}
24+
25+
public static async Task WhenAll(params Task[] tasks)
26+
{
27+
var allTasks = Task.WhenAll(tasks);
28+
29+
try
30+
{
31+
await allTasks;
32+
}
33+
catch (Exception)
34+
{
35+
// ignore
36+
}
37+
38+
throw allTasks.Exception ?? throw new ();
39+
}
40+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// <copyright file="ValueTaskHelper.cs" company="Zircon Technology">
2+
// This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution.
3+
// </copyright>
4+
5+
namespace ZirconNet.Core.Helpers;
6+
7+
public static class ValueTaskHelper
8+
{
9+
public static async ValueTask<T[]> WhenAll<T>(params ValueTask<T>[] tasks)
10+
{
11+
if (tasks == null)
12+
{
13+
throw new ArgumentNullException(nameof(tasks));
14+
}
15+
16+
if (tasks.Length == 0)
17+
{
18+
return Array.Empty<T>();
19+
}
20+
21+
List<Exception>? exceptions = null;
22+
23+
var results = new T[tasks.Length];
24+
for (var i = 0; i < tasks.Length; i++)
25+
{
26+
try
27+
{
28+
results[i] = await tasks[i].ConfigureAwait(false);
29+
}
30+
catch (Exception ex)
31+
{
32+
exceptions ??= new(tasks.Length);
33+
exceptions.Add(ex);
34+
}
35+
}
36+
37+
return exceptions is null
38+
? results
39+
: throw new AggregateException(exceptions);
40+
}
41+
42+
public static ValueTask<T[]> WhenAll<T>(IReadOnlyList<ValueTask<T>> tasks)
43+
{
44+
return WhenAll(tasks);
45+
}
46+
47+
public static ValueTask<T[]> WhenAll<T>(IEnumerable<ValueTask<T>> tasks)
48+
{
49+
return WhenAll(tasks);
50+
}
51+
52+
public static async ValueTask WhenAll(params ValueTask[] tasks)
53+
{
54+
if (tasks == null)
55+
{
56+
throw new ArgumentNullException(nameof(tasks));
57+
}
58+
59+
if (tasks.Length == 0)
60+
{
61+
return;
62+
}
63+
64+
List<Exception>? exceptions = null;
65+
66+
for (var i = 0; i < tasks.Length; i++)
67+
{
68+
try
69+
{
70+
await tasks[i].ConfigureAwait(false);
71+
}
72+
catch (Exception ex)
73+
{
74+
exceptions ??= new(tasks.Length);
75+
exceptions.Add(ex);
76+
}
77+
}
78+
79+
if (exceptions is null)
80+
{
81+
return;
82+
}
83+
84+
throw new AggregateException(exceptions!);
85+
}
86+
87+
public static ValueTask WhenAll(IReadOnlyList<ValueTask> tasks)
88+
{
89+
return WhenAll(tasks);
90+
}
91+
92+
public static ValueTask WhenAll(IEnumerable<ValueTask> tasks)
93+
{
94+
return WhenAll(tasks);
95+
}
96+
}

src/ZirconNet.Core/ZirconNet.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<IncludeSymbols>true</IncludeSymbols>
2020
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
2121
<EmbedUntrackedSources>true</EmbedUntrackedSources>
22-
<LangVersion>11.0</LangVersion>
22+
<LangVersion>12.0</LangVersion>
2323
</PropertyGroup>
2424

2525
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net6.0|AnyCPU'">

0 commit comments

Comments
 (0)