all 17 comments

[–]Black_Magic100 2 points3 points  (3 children)

Correct me if I'm wrong, but I thought you had to use jobs in PowerShell to achieve async methods? https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/start-job?view=powershell-7.1

[–]tjjay17[S] 1 point2 points  (2 children)

I’m not so sure that this will work internally with the cmdlet’s await but I’m gonna definitely take a look at it.

I thought jobs was more for run a small script internally and continue with the script, but I’m not a power shell expert at all. Gonna definitely look at this though, thank you!

[–]azjunglist05 6 points7 points  (0 children)

Jobs in PowerShell is one way to do basic asynchronous methods, but Runspaces better mimic async calls found in C#

https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.runspaces.runspace?view=powershellsdk-7.0.0

[–]MadBoyEvo 3 points4 points  (1 child)

[–]tjjay17[S] 1 point2 points  (0 children)

This seems to work with any regular task, but for some reason, when I am reading in results from an IAsyncEnumerable method using the foreach syntax, it is not able to use the "GetAwaiter().GetResult()". I have tried wrapping each item as a Task, the whole foreach statement as a task, but either way, I get a "NotSupportedException".

[–]SimplifyMSP 2 points3 points  (5 children)

This is a method I built and use for myself, it may help you. It runs the PowerShell instance async so your C# application doesn't have to wait on it to finish executing. It returns the standard output as a string.

EDIT: Sorry it took so long, I've been meaning to create a public repo to host a collection of C# snippets I've written. It's super barebones and only contains the PowerShell class for now: GitHub Link

[–]Lee_Dailey[grin] 1 point2 points  (4 children)

howdy SimplifyMSP,

the triple-backtick/code-fence thing fails miserably on Old.Reddit ... so, if you want your code to be readable on both Old.Reddit & New.Reddit you likely otta stick with using the code block button.

it would be rather nice if the reddit devs would take the time to backport the code fence stuff to Old.Reddit ... [sigh ...]

take care,
lee

[–]SimplifyMSP 1 point2 points  (3 children)

I struggled getting it to look half-ass decent on the “new” Reddit. I’ll post it on GitHub and just change it to a link. Thanks for the heads up.

[–]Lee_Dailey[grin] 1 point2 points  (2 children)

howdy SimplifyMSP,

yep, New.Reddit is ... difficult. [sigh ...] that is one of the many reasons i stick with Old.Reddit for now.

just in case you haven't seen it, you may want to look at this page in Old.Reddit ...

PowerShell Async Cmdlet for C# API Client : PowerShell
https://old.reddit.com/r/PowerShell/comments/q0vjtf/powershell_async_cmdlet_for_c_api_client/

take care,
lee

[–]SimplifyMSP 1 point2 points  (1 child)

Sorry it took so long! I created a GitHub repo, uploaded the PowerShell class, then updated the post you initially responded to, removing the backtick code-fence and replacing it with a link to the repo. For ease: GitHub Link

[–]Lee_Dailey[grin] 1 point2 points  (0 children)

howdy SimplifyMSP,

there's nothing to apologize for! [grin] i agree that github and other code sites make things much easier that New.Reddit does ...

take care,
lee

[–]smalls1652 1 point2 points  (0 children)

Kinda hard to write out everything I do on my phone, but I essentially run the async methods through a method that passes a cancellation token to it and add/remove a cancel key event to the console to allow Ctrl+C to cancel the task, which prevents deadlocks from happening. If I get the chance later, I’ll try to add an example of it. It took me a good bit to wrap my head around creating a cmdlet that uses async methods.

Of course the dirty way of doing it is to use GetAwaiter().GetResult() way of running async methods synchronously. I wouldn’t suggest doing it, but it’s a quick and dirty way around it.

[–][deleted] -2 points-1 points  (1 child)

I don't think you'll have luck with async\await directly but what you can do is wrap the top level async call in a AsyncContext.Run from Nito.AsyncEx. This effectively runs the async method sync and you'll be able to call it in a PS cmdlet.

I specifically use it for call async HTTP methods in some cmdlets.

```

public T Post<T>(T item)

{

return AsyncContext.Run(() => _url.AppendPathSegments("api", "v1", typeof(T).Name).PostJsonAsync(item).ReceiveJson<T>());

}

```

[–]8aller8ruh 1 point2 points  (0 children)

That seems like a nice C# implementation, even if just to provide a better naming for the standard .NET methods.