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
2 changes: 1 addition & 1 deletion apiCount.include.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
**API count: 326**
**API count: 327**
5 changes: 5 additions & 0 deletions api_list.include.md
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,11 @@
* `Task<TResult> WaitAsync<TResult>(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken))


#### TaskCompletionSource<T>

* `void SetCanceled<T>(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskcompletionsource-1.setcanceled#system-threading-tasks-taskcompletionsource-1-setcanceled(system-threading-cancellationtoken))


#### TextReader

* `ValueTask<Int32> ReadAsync(Memory<Char>, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken))
Expand Down
7 changes: 6 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The package targets `netstandard2.0` and is designed to support the following ru
* `net5.0`, `net6.0`, `net7.0`, `net8.0`, `net9.0`


**API count: 326**<!-- singleLineInclude: apiCount. path: /apiCount.include.md -->
**API count: 327**<!-- singleLineInclude: apiCount. path: /apiCount.include.md -->


**See [Milestones](../../milestones?state=closed) for release notes.**
Expand Down Expand Up @@ -739,6 +739,11 @@ The class `Polyfill` includes the following extension methods:
* `Task<TResult> WaitAsync<TResult>(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken))


#### TaskCompletionSource<T>

* `void SetCanceled<T>(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskcompletionsource-1.setcanceled#system-threading-tasks-taskcompletionsource-1-setcanceled(system-threading-cancellationtoken))


#### TextReader

* `ValueTask<Int32> ReadAsync(Memory<Char>, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken))
Expand Down
7 changes: 7 additions & 0 deletions src/Consume/Consume.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,13 @@ void CancellationTokenUnsafeRegister()
}, null);
}

void TaskCompletionSource_SetCanceled_WithCancellationToken()
{
var completionSource = new TaskCompletionSource<int>();
var tokenSource = new CancellationTokenSource();
completionSource.SetCanceled(tokenSource.Token);
}

async Task ProcessWaitForExitAsync()
{
var process = new Process();
Expand Down
37 changes: 37 additions & 0 deletions src/Polyfill/Polyfill_TaskCompletionSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// <auto-generated />
#pragma warning disable

#if !NET5_0_OR_GREATER

using System;
using System.Threading;
using System.Threading.Tasks;
using Link = System.ComponentModel.DescriptionAttribute;

static partial class Polyfill
{
/// <summary>
/// Transitions the underlying <see cref="Task{TResult}"/> into the <see cref="TaskStatus.Canceled"/> state
/// using the specified token.
/// </summary>
/// <param name="cancellationToken">The cancellation token with which to cancel the <see cref="Task{TResult}"/>.</param>
/// <exception cref="InvalidOperationException">
/// The underlying <see cref="Task{TResult}"/> is already in one of the three final states:
/// <see cref="TaskStatus.RanToCompletion"/>,
/// <see cref="TaskStatus.Faulted"/>, or
/// <see cref="TaskStatus.Canceled"/>.
/// </exception>
[Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskcompletionsource-1.setcanceled#system-threading-tasks-taskcompletionsource-1-setcanceled(system-threading-cancellationtoken)")]
public static void SetCanceled<T>(
this TaskCompletionSource<T> target,
CancellationToken cancellationToken)
{
if (target.TrySetCanceled(cancellationToken))
{
return;
}

throw new InvalidOperationException("An attempt was made to transition a task to a final state when it had already completed.");
}
}
#endif
28 changes: 28 additions & 0 deletions src/Tests/PolyfillTests_TaskCompletionSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma warning disable CS4014
partial class PolyfillTests
{
[Test]
public async Task TaskCompletionSource_SetCanceled_WithCancellationToken()
{
var completionSource = new TaskCompletionSource<int>();
var tokenSource = new CancellationTokenSource();

// Simulate some background work that will cancel the task
Task.Run(async () =>
{
await Task.Delay(20); // Simulate a delay
completionSource.SetCanceled(tokenSource.Token);
});

try
{
// Await the task
var result = await completionSource.Task;
Console.WriteLine($"Task completed with result: {result}");
}
catch (TaskCanceledException)
{
Console.WriteLine("Task was canceled.");
}
}
}