问题
Here is what I'd like to achieve in one way or another.
I have a custom assembly defining some objects. In my script, I create a custom object that I'd like to pass to a script block, keeping that object behavior.
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
How can I do that or achieve the same effect? Thanks for your help
回答1:
Instead of background jobs you may use PowerShell
with BeginInvoke
, EndInvoke
. Here is the simple but working example of passing a live object in a "job", changing it there, getting the results:
# 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
回答2:
Background jobs are built on top of PowerShell remoting and as such, perform similar actions when passing objects around. They would serialize/ deserialize them rather than pass them with all their complexity.
My guess is that the only way to get complex object is just to pass constructor arguments and/ or operations as -ArgumentList
and create object inside job.
In such a case also adding assembly would have to be part of the job:
Start-Job {
param ($ConstructorArguments)
Add-Type -AssemblyName MyCustomDll
$object = New-Object MyCustomDll.MyCustomObject $ConstructorArguments
$object | Get-Member
} -ArgumentList Foo, Bar | Wait-Job | Receive-Job
来源:https://stackoverflow.com/questions/15382728/passing-native-object-to-background-jobs