Estoy intentando averiguar cómo funciona ScriptBlock.GetNewClosure(). Sobre la base de this hilo (véase la respuesta de Stej) Tengo este código:ScriptBlock.GetNewClosure() Comportamiento
$i = 1
$block1 =
{
$i
}
$i = 2
$block2 =
{
$i
}
$i = 3
$block3 =
{
$i
}
& $block1
& $block2
& $block3
La salida es:
3
3
3
que se espera, ya que cuando se ejecutan los ScriptBlocks se utiliza el valor de $ i actual. Esto se puede cambiar usando GetNewClosure():
$i = 1
$block1 =
{
$i
}.GetNewClosure()
$i = 2
$block2 =
{
$i
}.GetNewClosure()
$i = 3
$block3 =
{
$i
}.GetNewClosure()
& $block1
& $block2
& $block3
Esta vez la salida es:
1
2
3
Esto es bueno, pero cuando trato de la estrella de la ScriptBlocks como puestos de trabajo:
$i = 1
$block1 =
{
$i
}.GetNewClosure()
$i = 2
$block2 =
{
$i
}.GetNewClosure()
$i = 3
$block3 =
{
$i
}.GetNewClosure()
$job1 = Start-Job $block1
$job1 | Wait-Job
$job1 | Receive-Job
$job2 = Start-Job $block2
$job2 | Wait-Job
$job2 | Receive-Job
$job3 = Start-Job $block3
$job3 | Wait-Job
$job3 | Receive-Job
No hay salida. Buscando una respuesta, encontré el hilo this, donde x0n dice que las tareas se ejecutan en un módulo dinámico. Los módulos tienen sessionstate aislado y comparten acceso a globales. Los cierres de PowerShell solo funcionan dentro de la misma cadena sessionstate/scope
¿Esto significa que $ i no es accesible desde los trabajos? Cuando pruebo su valor:
$i = 1
$block1 =
{
$i -eq $null
}.GetNewClosure()
$i = 2
$block2 =
{
$i -eq $null
}.GetNewClosure()
$i = 3
$block3 =
{
$i -eq $null
}.GetNewClosure()
$job1 = Start-Job $block1
$job1 | Wait-Job
$job1 | Receive-Job
$job2 = Start-Job $block2
$job2 | Wait-Job
$job2 | Receive-Job
$job3 = Start-Job $block3
$job3 | Wait-Job
$job3 | Receive-Job
$ es igual a nulo.
Gracias por la respuesta. ¿Este comportamiento está documentado por Microsoft? –
Bueno, yo diría que es una característica legal, pero la documentación al respecto podría ser mejor. Por cierto, en vez de 'param' en un bloque de script, puedes usar' $ args'. –