10

这是我想以一种或另一种方式实现的目标。

我有一个定义一些对象的自定义程序集。在我的脚本中,我创建了一个我想传递给脚本块的自定义对象,以保持该对象的行为。

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

我怎样才能做到这一点或达到相同的效果?谢谢你的帮助

4

2 回答 2

12

PowerShell您可以使用 ,BeginInvoke代替后台作业EndInvoke。这是在“作业”中传递活动对象的简单但有效的示例,在那里更改它,得到结果:

# 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
于 2013-03-13T13:43:41.437 回答
4

后台作业建立在 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 
于 2013-03-13T11:25:53.957 回答