首页 > 解决方案 > 从工作中触发事件

问题描述

我对powershell很陌生。如果您对 powershell 有所了解,我的问题很简单。

在下面的代码中,我试图从作为作业异步运行的一段代码中触发一个事件。由于某种原因,代码不起作用。

$callback = {
  param($event);
  Write "IN CALLBACK";
};

$jobScript = {
  while ($true) {
    sleep -s 1;
    "IN JOB SCRIPT";
    New-Event myEvent;
  }
}
Register-EngineEvent -SourceIdentifier myEvent -Action $callback;
Start-Job -Name Job -ScriptBlock $jobScript;

while ($true) {
  sleep -s 1;
  "IN LOOP";
}

预期输出:

IN LOOP
IN JOB SCRIPT
IN CALLBACK
IN LOOP 
IN JOB SCRIPT
IN CALLBACK
...

实际输出:

IN LOOP
IN LOOP 
IN LOOP
IN LOOP 
...

经过一番阅读,我改变了这一行

Start-Job -Name Job -ScriptBlock $jobScript

Start-Job -Name Job -ScriptBlock $jobScript | Wait-Job | Receive-Job;

我根本没有输出,因为工作永远不会完成。

这有点异步,但不是真的。在 JS 中完成会相当简单。

const fireEvent = (eventName) => { ... }
const subscribeToEvent = (eventName, callback) => { ... }
const callback = () => console.log('IN CALLBACK')

subscribeToEvent('myEvent', callback);

setInterval(() => {
   console.log('IN LOOP')
   fireEvent('myEvent');
}, 1000)

请帮忙!

标签: powershell

解决方案


跑步:

while ($true) {
  sleep -s 1;
  "IN LOOP";
}

永远只会给你:

IN LOOP
IN LOOP
IN LOOP
IN LOOP

运行此块:

$callback = {
  param($event);
  Write "IN CALLBACK";
};

$jobScript = {
  while ($true) {
    sleep -s 1;
    "IN JOB SCRIPT";
    New-Event myEvent;
  }
}
Register-EngineEvent -SourceIdentifier myEvent -Action $callback;
Start-Job -Name Job -ScriptBlock $jobScript;

给你一个名为 Job 的工作。此作业将一直运行,直到您停止它。作业的输出将是这样的:

get-job Job | receive-job
IN JOB SCRIPT

RunspaceId       : cf385728-926c-4dda-983e-6a5cfd4fd67f
ComputerName     :
EventIdentifier  : 1
Sender           :
SourceEventArgs  :
SourceArgs       : {}
SourceIdentifier : myEvent
TimeGenerated    : 6/15/2019 3:35:09 PM
MessageData      :

IN JOB SCRIPT
RunspaceId       : cf385728-926c-4dda-983e-6a5cfd4fd67f
ComputerName     :
EventIdentifier  : 2
Sender           :
SourceEventArgs  :
SourceArgs       : {}
SourceIdentifier : myEvent
TimeGenerated    : 6/15/2019 3:35:10 PM
MessageData      :


...

JavaScript 对我来说真的是希腊语,但您的问题似乎是该事件未在工作范围内注册。如果您将注册移至作业,它的行为会更像您的预期。

如果你这样做:

$jobScript = {
    $callback = {
        Write-Host "IN CALLBACK"
    }

    $null = Register-EngineEvent -SourceIdentifier myEvent -Action $callback

    while ($true) {
        sleep -s 1
        Write-Host "IN JOB SCRIPT"
        $Null = New-Event myEvent 
    }
}

$Null = Start-Job -Name Job -ScriptBlock $jobScript;

while ($true) {
    sleep -s 1
    "IN LOOP"
    Get-Job -Name Job | Receive-Job 
}

运行时$null = Register-EngineEvent ...$null = Start-Job ...您避免这些命令创建的对象显示在控制台上。此外,您不需要;在 PowerShell 中终止您的行。


推荐阅读