等待来自PowerShell的异步C#方法

Blu*_*les 8 c# powershell async-await

我想通过使用静态成员访问器从PowerShell调用静态异步C#方法,例如:

电源外壳

function CallMyStaticMethod([parameter(Mandatory=$true)][string]$myParam)
{
    ...
    [MyNamespace.MyClass]::MyStaticMethod($myParam)
    ...
}
Run Code Online (Sandbox Code Playgroud)

C#

public static async Task MyStaticMethod(string myParam)
{
    ...
    await ...
    ...
}
Run Code Online (Sandbox Code Playgroud)

因为我的C#方法是异步的,所以我的C#方法是否可以正常运行而没有来自PowerShell的某种"等待"调用?

Pat*_*cke 15

它会自行运行,但如果你想等到它完成,你可以使用它

$null = [MyNamespace.MyClass]::MyStaticMethod($myParam).GetAwaiter().GetResult()
Run Code Online (Sandbox Code Playgroud)

AggregateException如果您使用类似的东西,这将解开将被抛出的东西$task.Result.

然而,这将阻止直到它完成,这将阻止CTRL + C正确停止管道.您可以等待它完成,同时仍然遵守这样的管道停止

 $task = [MyNamespace.MyClass]::MyStaticMethod($myParam)
 while (-not $task.AsyncWaitHandle.WaitOne(200)) { }
 $null = $task.GetAwaiter().GetResult()
Run Code Online (Sandbox Code Playgroud)

如果异步方法实际返回了某些内容,请删除 $null =


JLR*_*she 8

借用 Patrick Meinecke 的回答,可以创建一个可管道化的函数来为您解决一个任务(或任务列表):

function Await-Task {
    param (
        [Parameter(ValueFromPipeline=$true, Mandatory=$true)]
        $task
    )

    process {
        while (-not $task.AsyncWaitHandle.WaitOne(200)) { }
        $task.GetAwaiter().GetResult()
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

$results = Get-SomeTasks $paramA $paramB | Await-Task
Run Code Online (Sandbox Code Playgroud)