gpt4 book ai didi

powershell - 无法在 `Register-ObjectEvent` 脚本 block 中调用类方法

转载 作者:行者123 更新时间:2023-12-05 01:22:31 24 4
gpt4 key购买 nike

我的目标是在收到作业时调用类方法,或者只是通知外部方法作业已完成。

有什么办法吗?这是示例脚本:

class Test {
$_Trigger

$_Event
$_Job
$_Result

Start() {

$this._Job = Start-Job -Name JobTest -ScriptBlock { Start-Sleep -Seconds 2; return 100; }

$this._Event = Register-ObjectEvent $this._Job StateChanged -Action {
$script:_Result = Receive-Job -Id $sender.Id -Keep
$this.Trigger() # this line here
}
}

Trigger() {
<#
CALL OTHER METHODS
#>
Write-Host "job complete"
}
}

我也尝试在这样调用作业时传递方法

Start-Job -Name JobTest -ScriptBlock { Start-Sleep -Seconds 2;返回 100; } -ArgumentList $this._Trigger

并希望通过 $Sender 访问它,因为有 $sender 变量,如 docs 所述,但我的问题是如何调用它或如何在脚本 block 中“查看”这个自动变量?

The value of the Action parameter can include the $Event, $EventSubscriber, $Sender, $EventArgs, and $Args automatic variables. These variables provide information about the event to the Action script block. For more information, see about_Automatic_Variables.

最佳答案

几件事。

如果你想调试你的脚本或者只是你的脚本在没有从 VsCode 运行时工作(例如:在生产环境中),你需要确保你的脚本不会退出得太快。确保这种情况不会发生的最简单方法是在末尾设置某种循环。

如果您尝试在 Register-ObjectEvent -Action 脚本 block 中放置一个断点并且确实收到一条消息指出“断点无法命中”,这是因为您的脚本已经退出并且调试器在您到达实际事件处理程序时分离。由于 VsCode 即使在您的脚本退出时也会保持 session ,因此事件处理程序将触发,但这不是可调试的版本。

$this 将是 Register-ObjectEvent -Action 脚本 block 上下文中的 $null。您需要将类作为消息数据传递 -MessageData @{This = $this } 并从操作 block 中作为 $Event.MessageData.This

访问它>

Action 脚本 block 中没有任何 Try/Catch。请注意,任何错误都会终止事件处理程序,并且如果抛出任何错误,事件处理程序也不会在之后触发。

这是您的示例,适用于解决这些问题。(注:我还加了青色)

class Test {
$_Trigger
$_Event
$_Job
$_Result

Start() {

$this._Job = Start-Job -Name JobTest -ScriptBlock { Start-Sleep -Seconds 2; return 100; }

$this._Event = Register-ObjectEvent $this._Job StateChanged -Action {
try {
$MyObject = $Event.MessageData.This
$MyObject._Result = Receive-Job -Id $sender.Id -Keep
$MyObject.Trigger() # this line here
}
catch {

}
} -MessageData @{This = $this }
}

Trigger() {
<#
CALL OTHER METHODS
#>
Write-Host "job complete" -ForegroundColor Cyan
}
}

$MyTestInstance = [Test]::new()
$MyTestInstance.Start()

# IMPORTANT
# You need some kind of loop to prevent the script of exiting immediately.
# If you don't have any, It will appear to work in vscode but won't work in production contexts
# You also won't be able to debug the code if the script debugger exitted

# We stay in the loop until we have a result.
while (!$$MyTestInstance._Result) {
Start-Sleep -Milliseconds 100
}

引用资料

VsCode and Powershell: How to debug and trace into code called by Register-ObjectEvent

Register-ObjectEvent

About Automatic Variables

关于powershell - 无法在 `Register-ObjectEvent` 脚本 block 中调用类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73902923/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com