From f68cfc80010b0695550c73b8afa0e5c1c31dfe5c Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Wed, 6 Mar 2019 10:30:31 -0800 Subject: [PATCH 1/2] Update the async APIs to directly return a Task without using async/await --- .../engine/hostifaces/PowerShell.cs | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/System.Management.Automation/engine/hostifaces/PowerShell.cs b/src/System.Management.Automation/engine/hostifaces/PowerShell.cs index 4fea236d9b7..2014d3d5cb1 100644 --- a/src/System.Management.Automation/engine/hostifaces/PowerShell.cs +++ b/src/System.Management.Automation/engine/hostifaces/PowerShell.cs @@ -3083,10 +3083,8 @@ public IAsyncResult BeginInvoke(PSDataCollection input, /// /// Object is disposed. /// - public async Task> InvokeAsync() - { - return await Task>.Factory.FromAsync(BeginInvoke(), _endInvokeMethod).ConfigureAwait(false); - } + public Task> InvokeAsync() + => Task>.Factory.FromAsync(BeginInvoke(), _endInvokeMethod); /// /// Invoke a PowerShell command asynchronously. @@ -3126,8 +3124,8 @@ public async Task> InvokeAsync() /// /// Object is disposed. /// - public async Task> InvokeAsync(PSDataCollection input) - => await Task>.Factory.FromAsync(BeginInvoke(input), _endInvokeMethod).ConfigureAwait(false); + public Task> InvokeAsync(PSDataCollection input) + => Task>.Factory.FromAsync(BeginInvoke(input), _endInvokeMethod); /// /// Invoke a PowerShell command asynchronously. @@ -3177,8 +3175,8 @@ public async Task> InvokeAsync(PSDataCollection /// /// Object is disposed. /// - public async Task> InvokeAsync(PSDataCollection input, PSInvocationSettings settings, AsyncCallback callback, object state) - => await Task>.Factory.FromAsync(BeginInvoke(input, settings, callback, state), _endInvokeMethod).ConfigureAwait(false); + public Task> InvokeAsync(PSDataCollection input, PSInvocationSettings settings, AsyncCallback callback, object state) + => Task>.Factory.FromAsync(BeginInvoke(input, settings, callback, state), _endInvokeMethod); /// /// Invoke a PowerShell command asynchronously. @@ -3225,8 +3223,8 @@ public async Task> InvokeAsync(PSDataCollection /// /// Object is disposed. /// - public async Task> InvokeAsync(PSDataCollection input, PSDataCollection output) - => await Task>.Factory.FromAsync(BeginInvoke(input, output), _endInvokeMethod).ConfigureAwait(false); + public Task> InvokeAsync(PSDataCollection input, PSDataCollection output) + => Task>.Factory.FromAsync(BeginInvoke(input, output), _endInvokeMethod); /// /// Invoke a PowerShell command asynchronously and collect @@ -3284,8 +3282,8 @@ public async Task> InvokeAsync(PSDat /// /// Object is disposed. /// - public async Task> InvokeAsync(PSDataCollection input, PSDataCollection output, PSInvocationSettings settings, AsyncCallback callback, object state) - => await Task>.Factory.FromAsync(BeginInvoke(input, output, settings, callback, state), _endInvokeMethod).ConfigureAwait(false); + public Task> InvokeAsync(PSDataCollection input, PSDataCollection output, PSInvocationSettings settings, AsyncCallback callback, object state) + => Task>.Factory.FromAsync(BeginInvoke(input, output, settings, callback, state), _endInvokeMethod); /// /// Begins a batch execution. @@ -3808,10 +3806,8 @@ public void EndStop(IAsyncResult asyncResult) /// /// Object is disposed. /// - public async Task StopAsync(AsyncCallback callback, object state) - { - await Task.Factory.FromAsync(BeginStop(callback, state), _endStopMethod).ConfigureAwait(false); - } + public Task StopAsync(AsyncCallback callback, object state) + => Task.Factory.FromAsync(BeginStop(callback, state), _endStopMethod); #endregion From 3933ada28f96fe0f52180dfd22881a8ccb9984eb Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Wed, 6 Mar 2019 14:13:42 -0800 Subject: [PATCH 2/2] Update tests --- .../Api/TaskBasedAsyncPowerShellAPI.Tests.ps1 | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/test/powershell/engine/Api/TaskBasedAsyncPowerShellAPI.Tests.ps1 b/test/powershell/engine/Api/TaskBasedAsyncPowerShellAPI.Tests.ps1 index 1d3d62cc399..8130eade2a0 100644 --- a/test/powershell/engine/Api/TaskBasedAsyncPowerShellAPI.Tests.ps1 +++ b/test/powershell/engine/Api/TaskBasedAsyncPowerShellAPI.Tests.ps1 @@ -84,15 +84,16 @@ try { It 'cannot invoke a single script asynchronously in a runspace that has not been opened' { $rs = [runspacefactory]::CreateRunspace() $ps = [powershell]::Create($rs) + try { - $r = $ps.AddScript('@(1..10).foreach{Start-Sleep -Milliseconds 500}').InvokeAsync() # This test is designed to fail. You cannot invoke PowerShell asynchronously # in a runspace that has not been opened. - $r.IsFaulted | Should -Be $true - $r.Exception -is [System.AggregateException] | Should -Be $true - $r.Exception.InnerException -is [System.Management.Automation.Runspaces.InvalidRunspaceStateException] | Should -Be $true - $r.Exception.InnerException.CurrentState | Should -Be 'BeforeOpen' - $r.Exception.InnerException.ExpectedState | Should -Be 'Opened' + $err = { $ps.AddScript('1+1').InvokeAsync() } | Should -Throw -ErrorId "InvalidRunspaceStateException" -PassThru + + $err.Exception | Should -BeOfType "System.Management.Automation.MethodInvocationException" + $err.Exception.InnerException | Should -BeOfType "System.Management.Automation.Runspaces.InvalidRunspaceStateException" + $err.Exception.InnerException.CurrentState | Should -Be 'BeforeOpen' + $err.Exception.InnerException.ExpectedState | Should -Be 'Opened' } finally { $ps.Dispose() $rs.Dispose() @@ -117,7 +118,7 @@ try { # This test is designed to fail. You cannot invoke PowerShell asynchronously # in the current runspace because nested PowerShell instances cannot be # invoked asynchronously - $err = { InvokeAsyncHelper -PowerShell $ps -Wait } | Should -Throw -ErrorId 'AggregateException' -PassThru + $err = { $ps.AddScript('1+1').InvokeAsync() } | Should -Throw -ErrorId 'PSInvalidOperationException' -PassThru GetInnerErrorId -Exception $err.Exception | Should -Be 'InvalidOperation' } finally { $ps.Dispose()