From: Fraser Waters Date: Tue, 25 Feb 2020 14:48:29 +0000 (+0000) Subject: Add TaskCompletionSource.SetCanceled(CancellationToken) (#32696) X-Git-Tag: submit/tizen/20210909.063632~9513 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6de3cd306cd052b1b7c5443a220b5d83a18d8c09;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Add TaskCompletionSource.SetCanceled(CancellationToken) (#32696) * Add TaskCompletionSource.SetCanceled(CancellationToken) api-approved by #30862 * Add to ref * SetCanceled(default) * Change some tests to use SetCaneled not TrySetCanceled These tests used SetResult/SetException and TrySetCancelled so it could pass a token. Changed to use SetCancelled to match the Result/Exception useage. * Add SetCanceled(CT) test * Check exception on re-cancel * Equal not Equals * Catch aggregate not TaskCancelled directly * Inner not exc * Markup * s/m/n --- diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskCompletionSource.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskCompletionSource.cs index 28773c7..911c0c9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskCompletionSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskCompletionSource.cs @@ -334,7 +334,29 @@ namespace System.Threading.Tasks /// The was disposed. public void SetCanceled() { - if (!TrySetCanceled()) + SetCanceled(default); + } + + /// + /// Transitions the underlying + /// into the + /// Canceled + /// state, and enables a token to be stored into the canceled + /// . + /// + /// The cancellation token to bind to this . + /// + /// The underlying is already in one + /// of the three final states: + /// RanToCompletion, + /// Faulted, or + /// Canceled. + /// + /// The was disposed. + public void SetCanceled(CancellationToken cancellationToken) + { + if (!TrySetCanceled(cancellationToken)) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted); } } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index ee19039..58a38eb 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -10630,6 +10630,7 @@ namespace System.Threading.Tasks public TaskCompletionSource(System.Threading.Tasks.TaskCreationOptions creationOptions) { } public System.Threading.Tasks.Task Task { get { throw null; } } public void SetCanceled() { } + public void SetCanceled(System.Threading.CancellationToken cancellationToken) { } public void SetException(System.Collections.Generic.IEnumerable exceptions) { } public void SetException(System.Exception exception) { } public void SetResult(TResult result) { } diff --git a/src/libraries/System.Threading.Tasks/tests/Task/TaskRtTests_Core.cs b/src/libraries/System.Threading.Tasks/tests/Task/TaskRtTests_Core.cs index 925f6cf..084d14e 100644 --- a/src/libraries/System.Threading.Tasks/tests/Task/TaskRtTests_Core.cs +++ b/src/libraries/System.Threading.Tasks/tests/Task/TaskRtTests_Core.cs @@ -391,6 +391,24 @@ namespace System.Threading.Tasks.Tests } [Fact] + public static void RunTaskCompletionSourceTests_SetCanceled() + { + CancellationTokenSource cts = new CancellationTokenSource(); + TaskCompletionSource tcs = new TaskCompletionSource(); + + tcs.SetCanceled(cts.Token); + + Assert.Equal(TaskStatus.Canceled, tcs.Task.Status); + + var ae = Assert.Throws(() => tcs.Task.Result); + var tce = Assert.IsType(ae.InnerException); + Assert.Equal(cts.Token, tce.CancellationToken); + + // Try to cancel again + Assert.Throws(() => tcs.SetCanceled(cts.Token)); + } + + [Fact] public static void RunTaskCompletionSourceTests_CancellationTests() { // Test that cancellation is persistent diff --git a/src/libraries/System.Threading.Tasks/tests/UnwrapTests.cs b/src/libraries/System.Threading.Tasks/tests/UnwrapTests.cs index dcbe93e..756e1e3 100644 --- a/src/libraries/System.Threading.Tasks/tests/UnwrapTests.cs +++ b/src/libraries/System.Threading.Tasks/tests/UnwrapTests.cs @@ -215,7 +215,7 @@ namespace System.Threading.Tasks.Tests innerTcs.SetException(new InvalidOperationException()); break; case TaskStatus.Canceled: - innerTcs.TrySetCanceled(CreateCanceledToken()); + innerTcs.SetCanceled(CreateCanceledToken()); break; } @@ -266,7 +266,7 @@ namespace System.Threading.Tasks.Tests innerTcs.SetException(new InvalidOperationException()); break; case TaskStatus.Canceled: - innerTcs.TrySetCanceled(CreateCanceledToken()); + innerTcs.SetCanceled(CreateCanceledToken()); break; } @@ -307,7 +307,7 @@ namespace System.Threading.Tasks.Tests outerTcs.SetResult(null); break; case TaskStatus.Canceled: - outerTcs.TrySetCanceled(CreateCanceledToken()); + outerTcs.SetCanceled(CreateCanceledToken()); break; case TaskStatus.Faulted: outerTcs.SetException(new InvalidCastException()); @@ -358,7 +358,7 @@ namespace System.Threading.Tasks.Tests outerTcs.SetResult(null); // cancellation break; case TaskStatus.Canceled: - outerTcs.TrySetCanceled(CreateCanceledToken()); + outerTcs.SetCanceled(CreateCanceledToken()); break; case TaskStatus.Faulted: outerTcs.SetException(new InvalidCastException());