diff --git a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs index d5830fae2..c90d26f41 100644 --- a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs +++ b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs @@ -1815,6 +1815,27 @@ public void TestAsyncAction() Assert.Equal(TaskStatus.Canceled, task.Status); } + [Fact] + public void TestAsyncActionWait() + { + var asyncAction = TestObject.DoitAsync(); + TestObject.CompleteAsync(); + asyncAction.Wait(); + Assert.Equal(AsyncStatus.Completed, asyncAction.Status); + + asyncAction = TestObject.DoitAsync(); + TestObject.CompleteAsync(E_FAIL); + var e = Assert.Throws(() => asyncAction.Wait()); + Assert.Equal(E_FAIL, e.InnerException.HResult); + Assert.Equal(AsyncStatus.Error, asyncAction.Status); + + asyncAction = TestObject.DoitAsync(); + asyncAction.Cancel(); + e = Assert.Throws(() => asyncAction.Wait()); + Assert.True(e.InnerException is TaskCanceledException); + Assert.Equal(AsyncStatus.Canceled, asyncAction.Status); + } + [Fact] public void TestAsyncActionRoundTrip() { @@ -1882,6 +1903,27 @@ public void TestAsyncActionWithProgress() Assert.Equal(TaskStatus.Canceled, task.Status); } + [Fact] + public void TestAsyncActionWithProgressWait() + { + var asyncAction = TestObject.DoitAsyncWithProgress(); + TestObject.CompleteAsync(); + asyncAction.Wait(); + Assert.Equal(AsyncStatus.Completed, asyncAction.Status); + + asyncAction = TestObject.DoitAsyncWithProgress(); + TestObject.CompleteAsync(E_FAIL); + var e = Assert.Throws(() => asyncAction.Wait()); + Assert.Equal(E_FAIL, e.InnerException.HResult); + Assert.Equal(AsyncStatus.Error, asyncAction.Status); + + asyncAction = TestObject.DoitAsyncWithProgress(); + asyncAction.Cancel(); + e = Assert.Throws(() => asyncAction.Wait()); + Assert.True(e.InnerException is TaskCanceledException); + Assert.Equal(AsyncStatus.Canceled, asyncAction.Status); + } + async Task InvokeAddAsync(int lhs, int rhs) { return await TestObject.AddAsync(lhs, rhs); @@ -1913,6 +1955,27 @@ public void TestAsyncOperation() Assert.Equal(TaskStatus.Canceled, task.Status); } + [Fact] + public void TestAsyncOperationWait() + { + var asyncOperation = TestObject.AddAsync(42, 8); + TestObject.CompleteAsync(); + asyncOperation.Wait(); + Assert.Equal(AsyncStatus.Completed, asyncOperation.Status); + + asyncOperation = TestObject.AddAsync(42, 8); + TestObject.CompleteAsync(E_FAIL); + var e = Assert.Throws(() => asyncOperation.Wait()); + Assert.Equal(E_FAIL, e.InnerException.HResult); + Assert.Equal(AsyncStatus.Error, asyncOperation.Status); + + asyncOperation = TestObject.AddAsync(42, 8); + asyncOperation.Cancel(); + e = Assert.Throws(() => asyncOperation.Wait()); + Assert.True(e.InnerException is TaskCanceledException); + Assert.Equal(AsyncStatus.Canceled, asyncOperation.Status); + } + [Fact] public void TestAsyncOperationRoundTrip() @@ -1983,6 +2046,27 @@ public void TestAsyncOperationWithProgress() Assert.Equal(TaskStatus.Canceled, task.Status); } + [Fact] + public void TestAsyncOperationWithProgressWait() + { + var asyncOperation = TestObject.AddAsyncWithProgress(42, 8); + TestObject.CompleteAsync(); + asyncOperation.Wait(); + Assert.Equal(AsyncStatus.Completed, asyncOperation.Status); + + asyncOperation = TestObject.AddAsyncWithProgress(42, 8); + TestObject.CompleteAsync(E_FAIL); + var e = Assert.Throws(() => asyncOperation.Wait()); + Assert.Equal(E_FAIL, e.InnerException.HResult); + Assert.Equal(AsyncStatus.Error, asyncOperation.Status); + + asyncOperation = TestObject.AddAsyncWithProgress(42, 8); + asyncOperation.Cancel(); + e = Assert.Throws(() => asyncOperation.Wait()); + Assert.True(e.InnerException is TaskCanceledException); + Assert.Equal(AsyncStatus.Canceled, asyncOperation.Status); + } + [Fact] public void TestPointTypeMapping() { diff --git a/src/cswinrt/strings/additions/Windows.Foundation/AsyncInfo.cs b/src/cswinrt/strings/additions/Windows.Foundation/AsyncInfo.cs index c43aaac31..81378030f 100644 --- a/src/cswinrt/strings/additions/Windows.Foundation/AsyncInfo.cs +++ b/src/cswinrt/strings/additions/Windows.Foundation/AsyncInfo.cs @@ -121,28 +121,28 @@ public static IAsyncOperationWithProgress Run CreateCompletedAction() + public static IAsyncActionWithProgress CompletedActionWithProgress() { var asyncInfo = new TaskToAsyncActionWithProgressAdapter(isCanceled: false); return asyncInfo; } - internal static IAsyncOperation CreateCompletedOperation(TResult synchronousResult) + public static IAsyncOperation FromResult(TResult synchronousResult) { var asyncInfo = new TaskToAsyncOperationAdapter(synchronousResult); return asyncInfo; } - internal static IAsyncOperationWithProgress CreateCompletedOperation(TResult synchronousResult) + public static IAsyncOperationWithProgress FromResultWithProgress(TResult synchronousResult) { var asyncInfo = new TaskToAsyncOperationWithProgressAdapter(synchronousResult); return asyncInfo; @@ -150,10 +150,9 @@ internal static IAsyncOperationWithProgress CreateCompletedO #endregion Factory methods for creating IAsyncInfo instances that have already completed synchronously - #region Factory methods for creating IAsyncInfo instances that have already completed synchronously with an error - internal static IAsyncAction CreateFaultedAction(Exception error) + public static IAsyncAction FromException(Exception error) { if (error == null) throw new ArgumentNullException(nameof(error)); @@ -167,7 +166,7 @@ internal static IAsyncAction CreateFaultedAction(Exception error) } - internal static IAsyncActionWithProgress CreateFaultedAction(Exception error) + public static IAsyncActionWithProgress FromExceptionWithProgress(Exception error) { if (error == null) throw new ArgumentNullException(nameof(error)); @@ -181,7 +180,7 @@ internal static IAsyncActionWithProgress CreateFaultedAction CreateFaultedOperation(Exception error) + public static IAsyncOperation FromException(Exception error) { if (error == null) throw new ArgumentNullException(nameof(error)); @@ -195,7 +194,7 @@ internal static IAsyncOperation CreateFaultedOperation(Excepti } - internal static IAsyncOperationWithProgress CreateFaultedOperation(Exception error) + public static IAsyncOperationWithProgress FromExceptionWithProgress(Exception error) { if (error == null) throw new ArgumentNullException(nameof(error)); @@ -207,7 +206,39 @@ internal static IAsyncOperationWithProgress CreateFaultedOpe return asyncInfo; } + #endregion Factory methods for creating IAsyncInfo instances that have already completed synchronously with an error + #region Factory methods for creating IAsyncInfo instances that have already been canceled synchronously + + public static IAsyncAction CanceledAction() + { + var asyncInfo = new TaskToAsyncActionAdapter(isCanceled: true); + return asyncInfo; + } + + + public static IAsyncActionWithProgress CanceledActionWithProgress() + { + var asyncInfo = new TaskToAsyncActionWithProgressAdapter(isCanceled: true); + return asyncInfo; + } + + + public static IAsyncOperation CanceledOperation() + { + var asyncInfo = new TaskToAsyncOperationAdapter(isCanceled: true); + return asyncInfo; + } + + + public static IAsyncOperationWithProgress CanceledOperationWithProgress() + { + var asyncInfo = new TaskToAsyncOperationWithProgressAdapter(isCanceled: true); + return asyncInfo; + } + + #endregion Factory methods for creating IAsyncInfo instances that have already been canceled synchronously + } // class AsyncInfo } // namespace diff --git a/src/cswinrt/strings/additions/Windows.Foundation/TaskToAsyncOperationAdapter.cs b/src/cswinrt/strings/additions/Windows.Foundation/TaskToAsyncOperationAdapter.cs index 6cf370263..e8c7f0b24 100644 --- a/src/cswinrt/strings/additions/Windows.Foundation/TaskToAsyncOperationAdapter.cs +++ b/src/cswinrt/strings/additions/Windows.Foundation/TaskToAsyncOperationAdapter.cs @@ -39,6 +39,13 @@ internal TaskToAsyncOperationAdapter(TResult synchronousResult) { } + internal TaskToAsyncOperationAdapter(bool isCanceled) + : base(default(TResult)) + { + if (isCanceled) + DangerousSetCanceled(); + } + public TResult GetResults() { return GetResultsInternal(); diff --git a/src/cswinrt/strings/additions/Windows.Foundation/TaskToAsyncOperationWithProgressAdapter.cs b/src/cswinrt/strings/additions/Windows.Foundation/TaskToAsyncOperationWithProgressAdapter.cs index e933814a9..9307b67f9 100644 --- a/src/cswinrt/strings/additions/Windows.Foundation/TaskToAsyncOperationWithProgressAdapter.cs +++ b/src/cswinrt/strings/additions/Windows.Foundation/TaskToAsyncOperationWithProgressAdapter.cs @@ -44,6 +44,13 @@ internal TaskToAsyncOperationWithProgressAdapter(TResult synchronousResult) { } + internal TaskToAsyncOperationWithProgressAdapter(bool isCanceled) + : base(default(TResult)) + { + if (isCanceled) + DangerousSetCanceled(); + } + public TResult GetResults() { return GetResultsInternal(); diff --git a/src/cswinrt/strings/additions/Windows.Foundation/Windows.Foundation.cs b/src/cswinrt/strings/additions/Windows.Foundation/Windows.Foundation.cs index c27bf8c79..506ecfe76 100644 --- a/src/cswinrt/strings/additions/Windows.Foundation/Windows.Foundation.cs +++ b/src/cswinrt/strings/additions/Windows.Foundation/Windows.Foundation.cs @@ -61,6 +61,11 @@ public static TaskAwaiter GetAwaiter(this IAsyncAction source) return AsTask(source).GetAwaiter(); } + public static void Wait(this IAsyncAction source) + { + AsTask(source).Wait(); + } + public static Task AsTask(this IAsyncOperation source, CancellationToken cancellationToken) { if (source == null) @@ -104,6 +109,16 @@ public static TaskAwaiter GetAwaiter(this IAsyncOperation(this IAsyncOperation source) + { + AsTask(source).Wait(); + } + + public static TResult Get(this IAsyncOperation source) + { + return AsTask(source).Result; + } + public static Task AsTask(this IAsyncActionWithProgress source, CancellationToken cancellationToken, IProgress progress) { if (source == null) @@ -169,6 +184,11 @@ public static TaskAwaiter GetAwaiter(this IAsyncActionWithProgress(this IAsyncActionWithProgress source) + { + AsTask(source).Wait(); + } + public static Task AsTask(this IAsyncOperationWithProgress source, CancellationToken cancellationToken, IProgress progress) { if (source == null) @@ -234,6 +254,16 @@ public static TaskAwaiter GetAwaiter(this IAsyncOpe return AsTask(source).GetAwaiter(); } + public static void Wait(this IAsyncOperationWithProgress source) + { + AsTask(source).Wait(); + } + + public static TResult Get(this IAsyncOperationWithProgress source) + { + return AsTask(source).Result; + } + public static IAsyncAction AsAsyncAction(this Task source) { if (source == null) diff --git a/src/cswinrt/strings/additions/Windows.Storage.Streams/StreamOperationsImplementation.cs b/src/cswinrt/strings/additions/Windows.Storage.Streams/StreamOperationsImplementation.cs index b14a652a5..e297596ba 100644 --- a/src/cswinrt/strings/additions/Windows.Storage.Streams/StreamOperationsImplementation.cs +++ b/src/cswinrt/strings/additions/Windows.Storage.Streams/StreamOperationsImplementation.cs @@ -53,11 +53,11 @@ internal static IAsyncOperationWithProgress ReadAsync_MemoryStrea if (dataBuffer.Length > 0) memStream.Seek(dataBuffer.Length, SeekOrigin.Current); - return AsyncInfo.CreateCompletedOperation(dataBuffer); + return AsyncInfo.FromResultWithProgress(dataBuffer); } catch (Exception ex) { - return AsyncInfo.CreateFaultedOperation(ex); + return AsyncInfo.FromExceptionWithProgress(ex); } } // ReadAsync_MemoryStream