2013-03-13 12 views
5

これは、私が何らかの方法で達成したいことです。"ネイティブ"オブジェクトをバックグラウンドジョブに渡す

いくつかのオブジェクトを定義するカスタムアセンブリがあります。私のスクリプトでは、スクリプトブロックに渡したいカスタムオブジェクトを作成し、そのオブジェクトの動作を維持します。

Add-Type -AssemblyName MyCustomDLL 

$global:object = new-object MyCustomDLL.MyCustomObject() 
$object | gm 

$jobWork = { param ($object) $object | gm } # I'd like to keep my object behavior in that block 

$job = Start-Job -ScriptBlock $jobWork -ArgumentList $object 
Wait-Job $job 
Receive-Job $job 

どうすれば同じ効果が得られますか?ご協力ありがとうございます

答えて

7

代わりにバックグラウンドジョブのあなたはBeginInvokePowerShellEndInvokeを使用することができます。

# live object to be passed in a job and changed there 
$liveObject = @{ data = 42} 

# job script 
$script = { 
    param($p1) 
    $p1.data # some output (42) 
    $p1.data = 3.14 # change the live object data 
} 

# create and start the job 
$p = [PowerShell]::Create() 
$null = $p.AddScript($script).AddArgument($liveObject) 
$job = $p.BeginInvoke() 

# wait for it to complete 
$done = $job.AsyncWaitHandle.WaitOne() 

# get the output, this line prints 42 
$p.EndInvoke($job) 

# show the changed live object (data = 3.14) 
$liveObject 
3

バックグラウンドジョブはPowerShellリモーティングの上に構築されているため、オブジェクトを渡す際に同様の操作を行います。彼らはそれらをすべて複雑にするのではなく、シリアライズ/デシリアライズします。

複雑なオブジェクトを取得する唯一の方法は、コンストラクタの引数や演算を-ArgumentListとして渡し、オブジェクトジョブ内に作成することです。このような場合には

もアセンブリを追加すると、ジョブの一部でなければならないであろう。

Start-Job { 
    param ($ConstructorArguments) 
    Add-Type -AssemblyName MyCustomDll 
    $object = New-Object MyCustomDll.MyCustomObject $ConstructorArguments 
    $object | Get-Member 
} -ArgumentList Foo, Bar | Wait-Job | Receive-Job 
+0

オブジェクトがステートフルで、呼び出し元のスクリプトの状態がすでに変更されている場合は、そのオブジェクトの状態が変更されています。助けにならないでしょう。シリアライズ/デシリアライズ以外のトラックがありますか? –

関連する問題