Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/Consume/Consume.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,13 @@ void Task_Methods()
new Task<int>(func).WaitAsync(CancellationToken.None);
new Task<int>(func).WaitAsync(TimeSpan.Zero);
new Task<int>(func).WaitAsync(TimeSpan.Zero, CancellationToken.None);
Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.None);
Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ContinueOnCapturedContext);
Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);
Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding);
Task.FromResult(0).ConfigureAwait(ConfigureAwaitOptions.None);
Task.FromResult(0).ConfigureAwait(ConfigureAwaitOptions.ContinueOnCapturedContext);
Task.FromResult(0).ConfigureAwait(ConfigureAwaitOptions.ForceYielding);
}

#if FeatureMemory
Expand Down
44 changes: 44 additions & 0 deletions src/Polyfill/ConfigureAwaitOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#if !NET8_0_OR_GREATER

namespace System.Threading.Tasks;

/// <summary>
/// Options to control behavior when awaiting.
/// </summary>
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.configureawaitoptions?view=net-11.0
[Flags]
#if PolyUseEmbeddedAttribute
[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
#endif
#if PolyPublic
public
#endif
enum ConfigureAwaitOptions
{
/// <summary>
/// No options specified.
/// </summary>
None = 0,

/// <summary>
/// Attempts to marshal the continuation back to the original <see cref="System.Threading.SynchronizationContext"/>
/// or <see cref="System.Threading.Tasks.TaskScheduler"/> present on the originating thread at the time of the await.
/// </summary>
ContinueOnCapturedContext = 1,

/// <summary>
/// Avoids throwing an exception at the completion of awaiting a <see cref="Task"/> that ends
/// in the <see cref="TaskStatus.Faulted"/> or <see cref="TaskStatus.Canceled"/> state.
/// </summary>
SuppressThrowing = 2,

/// <summary>
/// Forces an await on an already completed <see cref="Task"/> to behave as if the <see cref="Task"/>
/// wasn't yet completed, such that the current asynchronous method will be forced to yield its execution.
/// </summary>
ForceYielding = 4
}

#else
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.ConfigureAwaitOptions))]
#endif
78 changes: 78 additions & 0 deletions src/Polyfill/Polyfill_Task.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,81 @@ public static async Task<TResult> WaitAsync<TResult>(
}

#endif
#if !NET8_0_OR_GREATER

/// <summary>Configures an awaiter used to await this <see cref="Task"/>.</summary>
//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)
public static ConfiguredTaskAwaitable ConfigureAwait(this Task target, ConfigureAwaitOptions options)
{
if ((options & ~(ConfigureAwaitOptions.ContinueOnCapturedContext |
ConfigureAwaitOptions.SuppressThrowing |
ConfigureAwaitOptions.ForceYielding)) != 0)
{
throw new ArgumentOutOfRangeException(nameof(options));
}

var task = target;

if ((options & ConfigureAwaitOptions.ForceYielding) != 0)
{
task = ForceYieldAsync(task);

static async Task ForceYieldAsync(Task t)
{
await Task.Yield();
await t;
}
}

if ((options & ConfigureAwaitOptions.SuppressThrowing) != 0)
{
task = SuppressThrowAsync(task);

static async Task SuppressThrowAsync(Task t)
{
try
{
await t;
}
catch
{
}
}
}

return task.ConfigureAwait(
(options & ConfigureAwaitOptions.ContinueOnCapturedContext) != 0);
}

/// <summary>Configures an awaiter used to await this <see cref="Task{TResult}"/>.</summary>
//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)
public static ConfiguredTaskAwaitable<TResult> ConfigureAwait<TResult>(
this Task<TResult> target,
ConfigureAwaitOptions options)
{
if ((options & ~(ConfigureAwaitOptions.ContinueOnCapturedContext |
ConfigureAwaitOptions.ForceYielding)) != 0)
{
throw new ArgumentOutOfRangeException(nameof(options));
}

var task = target;

if ((options & ConfigureAwaitOptions.ForceYielding) != 0)
{
task = ForceYieldAsync(task);

static async Task<TResult> ForceYieldAsync(Task<TResult> t)
{
await Task.Yield();
return await t;
}
}

return task.ConfigureAwait(
(options & ConfigureAwaitOptions.ContinueOnCapturedContext) != 0);
}

#endif
}

35 changes: 35 additions & 0 deletions src/Split/net461/ConfigureAwaitOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// <auto-generated />
#pragma warning disable
namespace System.Threading.Tasks;
/// <summary>
/// Options to control behavior when awaiting.
/// </summary>
[System.Flags]
#if PolyUseEmbeddedAttribute
[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
#endif
#if PolyPublic
public
#endif
enum ConfigureAwaitOptions
{
/// <summary>
/// No options specified.
/// </summary>
None = 0,
/// <summary>
/// Attempts to marshal the continuation back to the original <see cref="System.Threading.SynchronizationContext"/> or
/// <see cref="System.Threading.Tasks.TaskScheduler"/> present on the originating thread at the time of the await.
/// </summary>
ContinueOnCapturedContext = 1,
/// <summary>
/// Avoids throwing an exception at the completion of awaiting a <see cref="Task"/> that ends in the
/// <see cref="TaskStatus.Faulted"/> or <see cref="TaskStatus.Canceled"/> state.
/// </summary>
SuppressThrowing = 2,
/// <summary>
/// Forces an await on an already completed <see cref="Task"/> to behave as if the <see cref="Task"/> wasn't yet
/// completed, such that the current asynchronous method will be forced to yield its execution.
/// </summary>
ForceYielding = 4
}
59 changes: 59 additions & 0 deletions src/Split/net461/Polyfill_Task.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,63 @@ public static async Task<TResult> WaitAsync<TResult>(
await ((Task) target).WaitAsync(timeout, cancellationToken);
return target.Result;
}
/// <summary>Configures an awaiter used to await this <see cref="Task"/>.</summary>
public static System.Runtime.CompilerServices.ConfiguredTaskAwaitable ConfigureAwait(this Task target, ConfigureAwaitOptions options)
{
if ((options & ~(ConfigureAwaitOptions.ContinueOnCapturedContext |
ConfigureAwaitOptions.SuppressThrowing |
ConfigureAwaitOptions.ForceYielding)) != 0)
{
throw new System.ArgumentOutOfRangeException(nameof(options));
}
var task = target;
if ((options & ConfigureAwaitOptions.ForceYielding) != 0)
{
task = ForceYieldAsync(task);
static async Task ForceYieldAsync(Task t)
{
await Task.Yield();
await t;
}
}
if ((options & ConfigureAwaitOptions.SuppressThrowing) != 0)
{
task = SuppressThrowAsync(task);
static async Task SuppressThrowAsync(Task t)
{
try
{
await t;
}
catch
{
}
}
}
return task.ConfigureAwait(
(options & ConfigureAwaitOptions.ContinueOnCapturedContext) != 0);
}
/// <summary>Configures an awaiter used to await this <see cref="Task{TResult}"/>.</summary>
public static System.Runtime.CompilerServices.ConfiguredTaskAwaitable<TResult> ConfigureAwait<TResult>(
this Task<TResult> target,
ConfigureAwaitOptions options)
{
if ((options & ~(ConfigureAwaitOptions.ContinueOnCapturedContext |
ConfigureAwaitOptions.ForceYielding)) != 0)
{
throw new System.ArgumentOutOfRangeException(nameof(options));
}
var task = target;
if ((options & ConfigureAwaitOptions.ForceYielding) != 0)
{
task = ForceYieldAsync(task);
static async Task<TResult> ForceYieldAsync(Task<TResult> t)
{
await Task.Yield();
return await t;
}
}
return task.ConfigureAwait(
(options & ConfigureAwaitOptions.ContinueOnCapturedContext) != 0);
}
}
35 changes: 35 additions & 0 deletions src/Split/net462/ConfigureAwaitOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// <auto-generated />
#pragma warning disable
namespace System.Threading.Tasks;
/// <summary>
/// Options to control behavior when awaiting.
/// </summary>
[System.Flags]
#if PolyUseEmbeddedAttribute
[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
#endif
#if PolyPublic
public
#endif
enum ConfigureAwaitOptions
{
/// <summary>
/// No options specified.
/// </summary>
None = 0,
/// <summary>
/// Attempts to marshal the continuation back to the original <see cref="System.Threading.SynchronizationContext"/> or
/// <see cref="System.Threading.Tasks.TaskScheduler"/> present on the originating thread at the time of the await.
/// </summary>
ContinueOnCapturedContext = 1,
/// <summary>
/// Avoids throwing an exception at the completion of awaiting a <see cref="Task"/> that ends in the
/// <see cref="TaskStatus.Faulted"/> or <see cref="TaskStatus.Canceled"/> state.
/// </summary>
SuppressThrowing = 2,
/// <summary>
/// Forces an await on an already completed <see cref="Task"/> to behave as if the <see cref="Task"/> wasn't yet
/// completed, such that the current asynchronous method will be forced to yield its execution.
/// </summary>
ForceYielding = 4
}
59 changes: 59 additions & 0 deletions src/Split/net462/Polyfill_Task.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,63 @@ public static async Task<TResult> WaitAsync<TResult>(
await ((Task) target).WaitAsync(timeout, cancellationToken);
return target.Result;
}
/// <summary>Configures an awaiter used to await this <see cref="Task"/>.</summary>
public static System.Runtime.CompilerServices.ConfiguredTaskAwaitable ConfigureAwait(this Task target, ConfigureAwaitOptions options)
{
if ((options & ~(ConfigureAwaitOptions.ContinueOnCapturedContext |
ConfigureAwaitOptions.SuppressThrowing |
ConfigureAwaitOptions.ForceYielding)) != 0)
{
throw new System.ArgumentOutOfRangeException(nameof(options));
}
var task = target;
if ((options & ConfigureAwaitOptions.ForceYielding) != 0)
{
task = ForceYieldAsync(task);
static async Task ForceYieldAsync(Task t)
{
await Task.Yield();
await t;
}
}
if ((options & ConfigureAwaitOptions.SuppressThrowing) != 0)
{
task = SuppressThrowAsync(task);
static async Task SuppressThrowAsync(Task t)
{
try
{
await t;
}
catch
{
}
}
}
return task.ConfigureAwait(
(options & ConfigureAwaitOptions.ContinueOnCapturedContext) != 0);
}
/// <summary>Configures an awaiter used to await this <see cref="Task{TResult}"/>.</summary>
public static System.Runtime.CompilerServices.ConfiguredTaskAwaitable<TResult> ConfigureAwait<TResult>(
this Task<TResult> target,
ConfigureAwaitOptions options)
{
if ((options & ~(ConfigureAwaitOptions.ContinueOnCapturedContext |
ConfigureAwaitOptions.ForceYielding)) != 0)
{
throw new System.ArgumentOutOfRangeException(nameof(options));
}
var task = target;
if ((options & ConfigureAwaitOptions.ForceYielding) != 0)
{
task = ForceYieldAsync(task);
static async Task<TResult> ForceYieldAsync(Task<TResult> t)
{
await Task.Yield();
return await t;
}
}
return task.ConfigureAwait(
(options & ConfigureAwaitOptions.ContinueOnCapturedContext) != 0);
}
}
35 changes: 35 additions & 0 deletions src/Split/net47/ConfigureAwaitOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// <auto-generated />
#pragma warning disable
namespace System.Threading.Tasks;
/// <summary>
/// Options to control behavior when awaiting.
/// </summary>
[System.Flags]
#if PolyUseEmbeddedAttribute
[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
#endif
#if PolyPublic
public
#endif
enum ConfigureAwaitOptions
{
/// <summary>
/// No options specified.
/// </summary>
None = 0,
/// <summary>
/// Attempts to marshal the continuation back to the original <see cref="System.Threading.SynchronizationContext"/> or
/// <see cref="System.Threading.Tasks.TaskScheduler"/> present on the originating thread at the time of the await.
/// </summary>
ContinueOnCapturedContext = 1,
/// <summary>
/// Avoids throwing an exception at the completion of awaiting a <see cref="Task"/> that ends in the
/// <see cref="TaskStatus.Faulted"/> or <see cref="TaskStatus.Canceled"/> state.
/// </summary>
SuppressThrowing = 2,
/// <summary>
/// Forces an await on an already completed <see cref="Task"/> to behave as if the <see cref="Task"/> wasn't yet
/// completed, such that the current asynchronous method will be forced to yield its execution.
/// </summary>
ForceYielding = 4
}
Loading
Loading