-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Update the task-based async APIs added to PowerShell to return a Task object directly #9079
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
rjmholt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change makes sense to me. The InvokeAsync method itself shouldn't be async, since it just wraps another asynchronous invocation. Therefore it should synchronously pass the handle back to the caller. Everything looks good -- just want to discuss the recommended overload to see if we can improve our usage of that.
| return await Task<PSDataCollection<PSObject>>.Factory.FromAsync(BeginInvoke(), _endInvokeMethod).ConfigureAwait(false); | ||
| } | ||
| public Task<PSDataCollection<PSObject>> InvokeAsync() | ||
| => Task<PSDataCollection<PSObject>>.Factory.FromAsync(BeginInvoke(), _endInvokeMethod); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The thing I'm curious about is that the documentation here says that the FromAsync overload taking an IAsyncResult rather than a Func<AsyncCallback, object, IAsyncResult> is slower.
I tried looking into this, and the doc written for wrapping the old API with the new one here, but I'm not quite sure what needs to be done to turn the BeginInvoke() method we have into the appropriate callback handler
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's an SO post that touches on this question
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's another one that has some more detail
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, after reading a bit more, it looks like the callback functionality would need to be supported by PowerShell itself and passed into a BeginInvoke() method we provide so that it can signal that the task is done.
I was proceeding under the impression that it might be possible to fudge that with a wrapping lambda based on the documentation's recommendation of "use this overload", but I'm guessing that's wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, our Begin/End implementation doesn't strictly conform to the APM contract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will improve?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a reason to update the existing APM APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was not addressed comment #8056 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can defer opening that issue until we get some real feedback on those async APIs that request performance enhancement.
Bruce brought that up mainly because when it was discussed in the committee meeting, there was an ask about if we should have separate implementation for the task-based APIs.
|
@daxian-dbw With the PR we get a possibility to use the methods in scripts, yes? So we need to update related doc issue. |
|
Scripts can use those new async APIs. They are tested in Pester. APIs are documented by its xml doc comments, right? I guess nothing needs to be done in the powershell-doc repo. @adityapatwardhan can you please confirm? |
… object directly (PowerShell#9079) Update the task-based async APIs added to PowerShell to not use the `aysnc/await` keywords, but to return a `Task` object directly. There is nothing to continue on after the `Task.Factory.FromAsync` call in those methods, so there is not need to use `aysnc` and `await` keywords, which turns the method into a state machine class unnecessarily. # Conflicts: # src/System.Management.Automation/engine/hostifaces/PowerShell.cs # test/powershell/engine/Api/TaskBasedAsyncPowerShellAPI.Tests.ps1
… object directly (#9079) Update the task-based async APIs added to PowerShell to not use the `aysnc/await` keywords, but to return a `Task` object directly. There is nothing to continue on after the `Task.Factory.FromAsync` call in those methods, so there is not need to use `aysnc` and `await` keywords, which turns the method into a state machine class unnecessarily.
PR Summary
Update the task-based async APIs added to PowerShell to not use the aysnc/await keywords, but to return a Task object directly.
There is nothing to continue on after the
Task.Factory.FromAsynccall in those methods, so there is not need to useaysncandawaitkeywords, which turns the method into a state machine class.The behavior of the API is slightly different comparing with before this change.
But note that, the behavior when calling the async APIs with
awaitis the same -- exception will be thrown atawait.Before this change:
Calling
InvokeAsync()withoutawaitwill always return a task even if theBeginInvokecall, which gets evaluated before callingFromAsync, throws an exception.This is because with
async/await, this method is written by compiler with a state machine, where all exceptions are caught can passed to the task that is going to be returned.After this change:
Calling
InvokeAsync()withoutawaitwill throw exception if theBeginInovkecall throws exception. So it fails early./cc @KirkMunro
PR Context
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:or[ WIP ]to the beginning of the title (theWIPbot will keep its status check atPendingwhile the prefix is present) and remove the prefix when the PR is ready.[feature]to your commit messages if the change is significant or affects feature tests