У меня есть функция mainFunction, которая получает 2 параметра - $name будет обычной строкой, а $moveFunction будет какой-то функцией.
Я хочу запустить работу ScriptBlock ($SB), которая будет вызывать $moveFunction с $name в качестве аргумента.
function foo($a){
Write-Output "In function foo with the argument => $a"
}
$SB = {
param($C, $fooFunction)
$fooFunction.Invoke($C)
}
function mainFunction($name, $moveFunction){
Start-Job -Name "currentJob" -ArgumentList $name, ${Function:$moveFunction} -ScriptBlock $SB
}
$j1 = mainFunction -name "output!" -moveFunction $Function:foo
Я проверил, что $moveFunction уже существует в mainFunction ($moveFunction.invoke(5) на mainFunction)
Я не могу найти проблему с передачей функции в качестве аргумента в стартовом задании.
а из Get-Job -Name "CurrentJob" | Receive-Job я получаю:
You cannot call a method on a null-valued expression.
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
+ PSComputerName : localhost
Любая помощь будет оценена.
редактировать:
Проблема, скорее всего, в том, как я передаю функцию в качестве аргумента (${Function:$moveFunction}
@RiverHeart В конце концов, ваш комментарий мне действительно помог. Добавь свой ответ Я одобряю =)

Вы передаете ту же функцию и вызываете ее. Вы можете напрямую использовать функцию в работе.
Start-Job -Name "currentJob" -ArgumentList $name - ScriptBlock ${function:foo}
Я посмотрю на твой ответ завтра подробно, но от быстрого бега не получается. Звонок по-прежнему $j1 = mainFunction -name "output!" -moveFunction $Function:foo?
Можно даже Start-Job -Name "currentJob" -ArgumentList $name, $Function:foo - ScriptBlock $SB
Мой комментарий сверху никто не читал? :( Это не работает, потому что блок сценария сериализуется и выводится в виде строки при передаче в задание. Вам нужно взять эту строку и сгенерировать новый блок сценария.
ага, де-сериализуется, не заметил вашего комментария.
@sheldonzy: вы можете напрямую вызывать функцию в задании.
Просто повторение моего предыдущего комментария плюс пример кода. Похожая проблема здесь. По сути, аргументы, передаваемые командам Jobs и Remote, сериализуются. Во время процесса десериализации функции и блоки скриптов выводятся в виде строк вместо своего исходного типа. К счастью, преобразовать их в вызываемые блоки сценариев с помощью [ScriptBlock]::Create("string") несложно.
function foo {
write-host "foo"
}
function bar {
# This argument comes in as a string
param($func)
write-host "bar"
# Create scriptblock from string
$func = [ScriptBlock]::Create($func)
$func.invoke()
}
Start-Job -ArgumentList $Function:Foo -ScriptBlock $Function:Bar
Get-Job | Wait-job
Get-Job | Receive-job
Я немного покопался, и похоже, что кто-то уже ответил на этот тип вопроса здесь. По сути, аргументы для заданий и удаленных команд сериализованы. ScriptBlock выходит на другом конце как String. Просто вызовите
$func = [ScriptBlock]::Create($func), чтобы преобразовать эту строку обратно в SB и вызвать как обычно.