Новое закрытие на блоке сценария

Рассмотрите этот код:

PS> $timer = New-Object Timers.Timer
PS> $timer.Interval = 1000
PS> $i = 1;
PS> Register-ObjectEvent $timer Elapsed -Action { write-host 'i: ' $i }.GetNewClosure()
PS> $timer.Enabled = 1
i:  1
i:  1
i:  1
 ...
# wait a couple of seconds and change $i
PS> $i = 2
i:  2
i:  2
i:  2

Я предположил это, когда я создаю новое закрытие ({ write-host 'i: ' $i }.GetNewClosure()) значение $i будет связан с этим закрытием. Но не в этом случае. Afer я изменяю значение, write-host принимает новое значение.

С другой стороны это работает:

PS> $i = 1;
PS> $action = { write-host 'i: ' $i }.GetNewClosure()
PS> &$action
i:  1
PS> $i = 2
PS> &$action
i:  1

Почему это не работает с Register-ObjectEvent?

7
задан Jon Seigel 12 April 2010 в 12:54
поделиться

2 ответа

Задания выполняются в динамическом модуле; модули имеют изолированное состояние сеанса и имеют общий доступ к глобальным объектам. Замыкания PowerShell работают только в той же цепочке состояния сеанса / области видимости. Раздражает, да.

-Oisin

шт. Я говорю «задания», потому что обработчики событий фактически являются локальными заданиями, ничем не отличными от сценария, запускаемого с помощью start-job (только локальный компьютер, неявно, без использования -computer localhost)

3
ответ дан 7 December 2019 в 16:41
поделиться

Я думаю, вы делаете предположения, которые не соответствуют действительности. PSH интерпретируется, поэтому когда создается блок кода, он просто содержит исходный код. При последующей оценке любые переменные, которые он использует, будут искаться обычным для PSH способом: сначала в текущей области видимости, а затем в каждой внешней области видимости, пока не будет найдена переменная с подходящим именем.

Когда таймер запускает свое событие, он выполняет блок кода и таким образом ищет $i.

Во втором случае, если просто использовать блок кода напрямую (удалить вызов GetNewClosure), то второе выполнение дает 2.

0
ответ дан 7 December 2019 в 16:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: