You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让PowerShell中基于Task的Async调用生成可用事件?有无替代工具?

处理PowerShell中基于Task的异步操作事件

不用强行将Task转换为IAsyncResult,直接利用Task的延续机制结合PowerShell原生事件系统,就能实现类似New-ScriptblockCallback的功能,让Task异步调用完成时触发可便捷使用的PowerShell事件。

自定义辅助函数

可以封装一个专门的辅助函数,用来生成Task完成时的回调,自动触发指定事件:

function New-TaskEventCallback {
    param(
        [Parameter(Mandatory)]
        [string]$EventName,
        [Parameter(Mandatory)]
        [scriptblock]$EventDataProcessor
    )

    return {
        param($task)
        if ($task.IsCompleted) {
            $eventData = if ($EventDataProcessor) {
                & $EventDataProcessor $task
            } else {
                $task
            }
            New-Event -SourceIdentifier $EventName -MessageData $eventData
        }
    }.GetNewClosure()
}

函数说明

  • EventName:指定Task完成时要触发的PowerShell事件名称
  • EventDataProcessor:可选脚本块,用于处理Task的结果(如提取状态、异常、关联对象等),生成最终传递给事件的自定义数据
  • 返回的委托可直接绑定到Task的ContinueWith方法,Task完成后自动触发事件

使用示例(以ClientWebSocket为例)

# 1. 定义事件处理逻辑
$onWebSocketConnected = {
    param($sender, $eventArgs)
    $eventData = $eventArgs.MessageData
    if ($eventData.Status -eq 'RanToCompletion') {
        Write-Host "WebSocket连接成功"
        # 这里可添加后续操作,比如发送测试消息
        $sendTask = $eventData.WebSocket.SendAsync(
            [System.ArraySegment[byte]][System.Text.Encoding]::UTF8.GetBytes("Hello WebSocket"),
            [System.Net.WebSockets.WebSocketMessageType]::Text,
            $true,
            [System.Threading.CancellationToken]::None
        )
        # 可继续绑定SendAsync的完成事件
        $sendCallback = New-TaskEventCallback -EventName "WebSocket.MessageSent" -EventDataProcessor { $_ }
        $sendTask.ContinueWith($sendCallback)
    } else {
        Write-Host "WebSocket连接失败:$($eventData.Exception.Message)"
    }
}

# 2. 注册事件
Register-EngineEvent -SourceIdentifier "WebSocket.Connected" -Action $onWebSocketConnected
Register-EngineEvent -SourceIdentifier "WebSocket.MessageSent" -Action {
    Write-Host "消息发送完成,任务状态:$($args[1].MessageData.Status)"
}

# 3. 发起异步WebSocket连接
$ws = [System.Net.WebSockets.ClientWebSocket]::new()
$connectTask = $ws.ConnectAsync([Uri]"wss://echo.websocket.org", [System.Threading.CancellationToken]::None)

# 4. 绑定Task完成回调
$callback = New-TaskEventCallback -EventName "WebSocket.Connected" -EventDataProcessor {
    param($task)
    return @{
        Status = $task.Status
        WebSocket = $ws
        Exception = $task.Exception
    }
}
$connectTask.ContinueWith($callback)

关键注意事项

  • 完全基于Task异步API,符合微软弃用Begin/End模型后的推荐方向
  • 触发的事件可与PowerShell原生事件(如Register-ObjectEvent注册的事件)无缝混合使用
  • 可在EventDataProcessor中灵活处理Task的结果、异常等信息,按需传递给事件处理逻辑

内容的提问来源于stack exchange,提问作者Alain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 06:25:33