2010-10-30 22 views
8

ScriptBlock.GetNewClosure() nasıl çalıştığını anlamaya çalışıyorum.ScriptBlock.GetNewClosure() Davranış

$i = 1 
$block1 = 
{ 
    $i 
} 

$i = 2 
$block2 = 
{ 
    $i 
} 

$i = 3 
$block3 = 
{ 
    $i 
} 


& $block1 
& $block2 
& $block3 

çıkışı: ScriptBlocks yürütüldüğünde

bekleniyor
3 
3 
3 

, şimdiki $ i değeri kullanıldığından this parçacığı dayanarak Bu kodu vardır (Stej cevabını bakın). Bu GetNewClosure() kullanılarak değiştirilebilir:

$i = 1 
$block1 = 
{ 
    $i 
}.GetNewClosure() 

$i = 2 
$block2 = 
{ 
    $i 
}.GetNewClosure() 

$i = 3 
$block3 = 
{ 
    $i 
}.GetNewClosure() 


& $block1 
& $block2 
& $block3 

çıktı Bu kez:

$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 
:

1 
2 
3 

Bu iyidir, ama ben işler olarak ScriptBlocks yıldız çalıştığınızda

Çıkış yok. Bir cevap ararken, this iş parçacığı buldum, burada x0n işlerin dinamik bir modülde yürütüldüğünü söylüyor. Modüller izole oturumları vardır ve globals'a erişimi paylaşırlar. PowerShell kapanışları yalnızca aynı oturum açma/kapsam zincirinde çalışır

Bu, $ i'nin işlerden erişilemediği anlamına mı geliyor? Değerini sınandığımda:

$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 

$ null değerine eşittir.

cevap

6

Evet, bu, $i'un bu şekilde işlerden erişilemediği anlamına gelir. Ne yazık ki. Yani, başka bir yol kullanmak: örneğin, bir komut dosyası bloğunda param bir iş olarak çağrılan ve gereken Start-Job arasında ArgumentList parametre:

$i = 42 
$block1 = 
{ 
    param($i) 
    $i * 2 
} 

$job1 = Start-Job $block1 -ArgumentList $i 
$job1 | Wait-Job | Receive-Job 

Çıktı:

84 

Not; Aynı GetNewClosure da Register-ObjectEvent ile çalışmıyor olduğu bildirilmektedir: https://connect.microsoft.com/PowerShell/feedback/details/541754/getnewclosure-doesnt-work-on-register-objectevent

+0

cevap için teşekkür ederiz. Bu davranış Microsoft tarafından belgeleniyor mu? –

+0

Bunun yasal bir özellik olduğunu söyleyebilirim, ancak bununla ilgili belgeler daha iyi olabilir. BTW, bir komut satırında 'param' yerine '$ args' kullanabilirsiniz. –

-1
$i = 1 
$block1 = {"block 1 is $using:i" }.GetNewClosure() 

$i = 2 
$block2 = { "block 2 is $using:i" }.GetNewClosure() 

$job1 = Start-Job $block1 
$job1 | Wait-Job 
$job1 | Receive-Job 

$job2 = Start-Job $block2 
$job2 | Wait-Job 
$job2 | Receive-Job 

http://www.powertheshell.com/closure/