Skip to content

Commit 967d608

Browse files
committed
2 parents 4379881 + c5a3507 commit 967d608

40 files changed

Lines changed: 1958 additions & 0 deletions

src/Consume/Consume.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,13 @@ void Task_Methods()
14011401
new Task<int>(func).WaitAsync(CancellationToken.None);
14021402
new Task<int>(func).WaitAsync(TimeSpan.Zero);
14031403
new Task<int>(func).WaitAsync(TimeSpan.Zero, CancellationToken.None);
1404+
Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.None);
1405+
Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ContinueOnCapturedContext);
1406+
Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);
1407+
Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding);
1408+
Task.FromResult(0).ConfigureAwait(ConfigureAwaitOptions.None);
1409+
Task.FromResult(0).ConfigureAwait(ConfigureAwaitOptions.ContinueOnCapturedContext);
1410+
Task.FromResult(0).ConfigureAwait(ConfigureAwaitOptions.ForceYielding);
14041411
}
14051412

14061413
#if FeatureMemory
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#if !NET8_0_OR_GREATER
2+
3+
namespace System.Threading.Tasks;
4+
5+
/// <summary>
6+
/// Options to control behavior when awaiting.
7+
/// </summary>
8+
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.configureawaitoptions?view=net-11.0
9+
[Flags]
10+
#if PolyUseEmbeddedAttribute
11+
[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
12+
#endif
13+
#if PolyPublic
14+
public
15+
#endif
16+
enum ConfigureAwaitOptions
17+
{
18+
/// <summary>
19+
/// No options specified.
20+
/// </summary>
21+
None = 0,
22+
23+
/// <summary>
24+
/// Attempts to marshal the continuation back to the original <see cref="System.Threading.SynchronizationContext"/>
25+
/// or <see cref="System.Threading.Tasks.TaskScheduler"/> present on the originating thread at the time of the await.
26+
/// </summary>
27+
ContinueOnCapturedContext = 1,
28+
29+
/// <summary>
30+
/// Avoids throwing an exception at the completion of awaiting a <see cref="Task"/> that ends
31+
/// in the <see cref="TaskStatus.Faulted"/> or <see cref="TaskStatus.Canceled"/> state.
32+
/// </summary>
33+
SuppressThrowing = 2,
34+
35+
/// <summary>
36+
/// Forces an await on an already completed <see cref="Task"/> to behave as if the <see cref="Task"/>
37+
/// wasn't yet completed, such that the current asynchronous method will be forced to yield its execution.
38+
/// </summary>
39+
ForceYielding = 4
40+
}
41+
42+
#else
43+
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.ConfigureAwaitOptions))]
44+
#endif

src/Polyfill/Polyfill_Task.cs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,81 @@ public static async Task<TResult> WaitAsync<TResult>(
107107
}
108108

109109
#endif
110+
#if !NET8_0_OR_GREATER
111+
112+
/// <summary>Configures an awaiter used to await this <see cref="Task"/>.</summary>
113+
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.configureawait?view=net-11.0#system-threading-tasks-task-configureawait(system-threading-tasks-configureawaitoptions)
114+
public static ConfiguredTaskAwaitable ConfigureAwait(this Task target, ConfigureAwaitOptions options)
115+
{
116+
if ((options & ~(ConfigureAwaitOptions.ContinueOnCapturedContext |
117+
ConfigureAwaitOptions.SuppressThrowing |
118+
ConfigureAwaitOptions.ForceYielding)) != 0)
119+
{
120+
throw new ArgumentOutOfRangeException(nameof(options));
121+
}
122+
123+
var task = target;
124+
125+
if ((options & ConfigureAwaitOptions.ForceYielding) != 0)
126+
{
127+
task = ForceYieldAsync(task);
128+
129+
static async Task ForceYieldAsync(Task t)
130+
{
131+
await Task.Yield();
132+
await t;
133+
}
134+
}
135+
136+
if ((options & ConfigureAwaitOptions.SuppressThrowing) != 0)
137+
{
138+
task = SuppressThrowAsync(task);
139+
140+
static async Task SuppressThrowAsync(Task t)
141+
{
142+
try
143+
{
144+
await t;
145+
}
146+
catch
147+
{
148+
}
149+
}
150+
}
151+
152+
return task.ConfigureAwait(
153+
(options & ConfigureAwaitOptions.ContinueOnCapturedContext) != 0);
154+
}
155+
156+
/// <summary>Configures an awaiter used to await this <see cref="Task{TResult}"/>.</summary>
157+
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.configureawait?view=net-11.0#system-threading-tasks-task-1-configureawait(system-threading-tasks-configureawaitoptions)
158+
public static ConfiguredTaskAwaitable<TResult> ConfigureAwait<TResult>(
159+
this Task<TResult> target,
160+
ConfigureAwaitOptions options)
161+
{
162+
if ((options & ~(ConfigureAwaitOptions.ContinueOnCapturedContext |
163+
ConfigureAwaitOptions.ForceYielding)) != 0)
164+
{
165+
throw new ArgumentOutOfRangeException(nameof(options));
166+
}
167+
168+
var task = target;
169+
170+
if ((options & ConfigureAwaitOptions.ForceYielding) != 0)
171+
{
172+
task = ForceYieldAsync(task);
173+
174+
static async Task<TResult> ForceYieldAsync(Task<TResult> t)
175+
{
176+
await Task.Yield();
177+
return await t;
178+
}
179+
}
180+
181+
return task.ConfigureAwait(
182+
(options & ConfigureAwaitOptions.ContinueOnCapturedContext) != 0);
183+
}
184+
185+
#endif
186+
}
187+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// <auto-generated />
2+
#pragma warning disable
3+
namespace System.Threading.Tasks;
4+
/// <summary>
5+
/// Options to control behavior when awaiting.
6+
/// </summary>
7+
[System.Flags]
8+
#if PolyUseEmbeddedAttribute
9+
[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
10+
#endif
11+
#if PolyPublic
12+
public
13+
#endif
14+
enum ConfigureAwaitOptions
15+
{
16+
/// <summary>
17+
/// No options specified.
18+
/// </summary>
19+
None = 0,
20+
/// <summary>
21+
/// Attempts to marshal the continuation back to the original <see cref="System.Threading.SynchronizationContext"/> or
22+
/// <see cref="System.Threading.Tasks.TaskScheduler"/> present on the originating thread at the time of the await.
23+
/// </summary>
24+
ContinueOnCapturedContext = 1,
25+
/// <summary>
26+
/// Avoids throwing an exception at the completion of awaiting a <see cref="Task"/> that ends in the
27+
/// <see cref="TaskStatus.Faulted"/> or <see cref="TaskStatus.Canceled"/> state.
28+
/// </summary>
29+
SuppressThrowing = 2,
30+
/// <summary>
31+
/// Forces an await on an already completed <see cref="Task"/> to behave as if the <see cref="Task"/> wasn't yet
32+
/// completed, such that the current asynchronous method will be forced to yield its execution.
33+
/// </summary>
34+
ForceYielding = 4
35+
}

src/Split/net461/Polyfill_Task.cs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,63 @@ public static async Task<TResult> WaitAsync<TResult>(
8282
await ((Task) target).WaitAsync(timeout, cancellationToken);
8383
return target.Result;
8484
}
85+
/// <summary>Configures an awaiter used to await this <see cref="Task"/>.</summary>
86+
public static System.Runtime.CompilerServices.ConfiguredTaskAwaitable ConfigureAwait(this Task target, ConfigureAwaitOptions options)
87+
{
88+
if ((options & ~(ConfigureAwaitOptions.ContinueOnCapturedContext |
89+
ConfigureAwaitOptions.SuppressThrowing |
90+
ConfigureAwaitOptions.ForceYielding)) != 0)
91+
{
92+
throw new System.ArgumentOutOfRangeException(nameof(options));
93+
}
94+
var task = target;
95+
if ((options & ConfigureAwaitOptions.ForceYielding) != 0)
96+
{
97+
task = ForceYieldAsync(task);
98+
static async Task ForceYieldAsync(Task t)
99+
{
100+
await Task.Yield();
101+
await t;
102+
}
103+
}
104+
if ((options & ConfigureAwaitOptions.SuppressThrowing) != 0)
105+
{
106+
task = SuppressThrowAsync(task);
107+
static async Task SuppressThrowAsync(Task t)
108+
{
109+
try
110+
{
111+
await t;
112+
}
113+
catch
114+
{
115+
}
116+
}
117+
}
118+
return task.ConfigureAwait(
119+
(options & ConfigureAwaitOptions.ContinueOnCapturedContext) != 0);
120+
}
121+
/// <summary>Configures an awaiter used to await this <see cref="Task{TResult}"/>.</summary>
122+
public static System.Runtime.CompilerServices.ConfiguredTaskAwaitable<TResult> ConfigureAwait<TResult>(
123+
this Task<TResult> target,
124+
ConfigureAwaitOptions options)
125+
{
126+
if ((options & ~(ConfigureAwaitOptions.ContinueOnCapturedContext |
127+
ConfigureAwaitOptions.ForceYielding)) != 0)
128+
{
129+
throw new System.ArgumentOutOfRangeException(nameof(options));
130+
}
131+
var task = target;
132+
if ((options & ConfigureAwaitOptions.ForceYielding) != 0)
133+
{
134+
task = ForceYieldAsync(task);
135+
static async Task<TResult> ForceYieldAsync(Task<TResult> t)
136+
{
137+
await Task.Yield();
138+
return await t;
139+
}
140+
}
141+
return task.ConfigureAwait(
142+
(options & ConfigureAwaitOptions.ContinueOnCapturedContext) != 0);
143+
}
85144
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// <auto-generated />
2+
#pragma warning disable
3+
namespace System.Threading.Tasks;
4+
/// <summary>
5+
/// Options to control behavior when awaiting.
6+
/// </summary>
7+
[System.Flags]
8+
#if PolyUseEmbeddedAttribute
9+
[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
10+
#endif
11+
#if PolyPublic
12+
public
13+
#endif
14+
enum ConfigureAwaitOptions
15+
{
16+
/// <summary>
17+
/// No options specified.
18+
/// </summary>
19+
None = 0,
20+
/// <summary>
21+
/// Attempts to marshal the continuation back to the original <see cref="System.Threading.SynchronizationContext"/> or
22+
/// <see cref="System.Threading.Tasks.TaskScheduler"/> present on the originating thread at the time of the await.
23+
/// </summary>
24+
ContinueOnCapturedContext = 1,
25+
/// <summary>
26+
/// Avoids throwing an exception at the completion of awaiting a <see cref="Task"/> that ends in the
27+
/// <see cref="TaskStatus.Faulted"/> or <see cref="TaskStatus.Canceled"/> state.
28+
/// </summary>
29+
SuppressThrowing = 2,
30+
/// <summary>
31+
/// Forces an await on an already completed <see cref="Task"/> to behave as if the <see cref="Task"/> wasn't yet
32+
/// completed, such that the current asynchronous method will be forced to yield its execution.
33+
/// </summary>
34+
ForceYielding = 4
35+
}

src/Split/net462/Polyfill_Task.cs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,63 @@ public static async Task<TResult> WaitAsync<TResult>(
8282
await ((Task) target).WaitAsync(timeout, cancellationToken);
8383
return target.Result;
8484
}
85+
/// <summary>Configures an awaiter used to await this <see cref="Task"/>.</summary>
86+
public static System.Runtime.CompilerServices.ConfiguredTaskAwaitable ConfigureAwait(this Task target, ConfigureAwaitOptions options)
87+
{
88+
if ((options & ~(ConfigureAwaitOptions.ContinueOnCapturedContext |
89+
ConfigureAwaitOptions.SuppressThrowing |
90+
ConfigureAwaitOptions.ForceYielding)) != 0)
91+
{
92+
throw new System.ArgumentOutOfRangeException(nameof(options));
93+
}
94+
var task = target;
95+
if ((options & ConfigureAwaitOptions.ForceYielding) != 0)
96+
{
97+
task = ForceYieldAsync(task);
98+
static async Task ForceYieldAsync(Task t)
99+
{
100+
await Task.Yield();
101+
await t;
102+
}
103+
}
104+
if ((options & ConfigureAwaitOptions.SuppressThrowing) != 0)
105+
{
106+
task = SuppressThrowAsync(task);
107+
static async Task SuppressThrowAsync(Task t)
108+
{
109+
try
110+
{
111+
await t;
112+
}
113+
catch
114+
{
115+
}
116+
}
117+
}
118+
return task.ConfigureAwait(
119+
(options & ConfigureAwaitOptions.ContinueOnCapturedContext) != 0);
120+
}
121+
/// <summary>Configures an awaiter used to await this <see cref="Task{TResult}"/>.</summary>
122+
public static System.Runtime.CompilerServices.ConfiguredTaskAwaitable<TResult> ConfigureAwait<TResult>(
123+
this Task<TResult> target,
124+
ConfigureAwaitOptions options)
125+
{
126+
if ((options & ~(ConfigureAwaitOptions.ContinueOnCapturedContext |
127+
ConfigureAwaitOptions.ForceYielding)) != 0)
128+
{
129+
throw new System.ArgumentOutOfRangeException(nameof(options));
130+
}
131+
var task = target;
132+
if ((options & ConfigureAwaitOptions.ForceYielding) != 0)
133+
{
134+
task = ForceYieldAsync(task);
135+
static async Task<TResult> ForceYieldAsync(Task<TResult> t)
136+
{
137+
await Task.Yield();
138+
return await t;
139+
}
140+
}
141+
return task.ConfigureAwait(
142+
(options & ConfigureAwaitOptions.ContinueOnCapturedContext) != 0);
143+
}
85144
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// <auto-generated />
2+
#pragma warning disable
3+
namespace System.Threading.Tasks;
4+
/// <summary>
5+
/// Options to control behavior when awaiting.
6+
/// </summary>
7+
[System.Flags]
8+
#if PolyUseEmbeddedAttribute
9+
[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
10+
#endif
11+
#if PolyPublic
12+
public
13+
#endif
14+
enum ConfigureAwaitOptions
15+
{
16+
/// <summary>
17+
/// No options specified.
18+
/// </summary>
19+
None = 0,
20+
/// <summary>
21+
/// Attempts to marshal the continuation back to the original <see cref="System.Threading.SynchronizationContext"/> or
22+
/// <see cref="System.Threading.Tasks.TaskScheduler"/> present on the originating thread at the time of the await.
23+
/// </summary>
24+
ContinueOnCapturedContext = 1,
25+
/// <summary>
26+
/// Avoids throwing an exception at the completion of awaiting a <see cref="Task"/> that ends in the
27+
/// <see cref="TaskStatus.Faulted"/> or <see cref="TaskStatus.Canceled"/> state.
28+
/// </summary>
29+
SuppressThrowing = 2,
30+
/// <summary>
31+
/// Forces an await on an already completed <see cref="Task"/> to behave as if the <see cref="Task"/> wasn't yet
32+
/// completed, such that the current asynchronous method will be forced to yield its execution.
33+
/// </summary>
34+
ForceYielding = 4
35+
}

0 commit comments

Comments
 (0)