How do I Start a job of a function i just defined?

后端 未结 7 777
臣服心动
臣服心动 2020-11-27 23:34

How do I Start a job of a function i just defined?

function FOO { write-host \"HEY\" } Start-Job -ScriptBlock { FOO } |
Receive-Job

Receive-Job: The term \'         


        
相关标签:
7条回答
  • 2020-11-27 23:47

    It worked for me as:

    Start-Job -ScriptBlock ${Function:FOO}
    
    0 讨论(0)
  • 2020-11-27 23:51

    A slightly different take. A function is just a scriptblock assigned to a variable. Oh, it has to be a threadjob. It can't be foreach-object -parallel.

    $func = { 'hi' } # or
    function hi { 'hi' }; $func = $function:hi
    
    start-threadjob { & $using:func } | receive-job -auto -wait
    
    hi
    
    0 讨论(0)
  • 2020-11-28 00:04

    @Rynant's suggestion of InitializationScript is great

    I thought the purpose of (script) blocks is so that you can pass them around. So depending on how you are doing it, I would say go for:

    $FOO = {write-host "HEY"}
    
    Start-Job -ScriptBlock $FOO | wait-job |Receive-Job
    

    Of course you can parameterize script blocks as well:

    $foo = {param($bar) write-host $bar}
    
    Start-Job -ScriptBlock $foo -ArgumentList "HEY" | wait-job | receive-job
    
    0 讨论(0)
  • 2020-11-28 00:04

    An improvement to @Rynant's answer:

    You can define the function as normal in the main body of your script:

    Function FOO 
    { 
      Write-Host "HEY" 
    } 
    

    and then recycle this definition within a scriptblock:

    $export_functions = [scriptblock]::Create(@"
      Function Foo { $function:FOO }
    "@)
    

    (makes more sense if you have a substantial function body) and then pass them to Start-Job as above:

    Start-Job -ScriptBlock {FOO} -InitializationScript $export_functions| Wait-Job | Receive-Job
    

    I like this way, as it is easier to debug jobs by running them locally under the debugger.

    0 讨论(0)
  • 2020-11-28 00:04

    @Ben Power's comment under the accepted answer was my concern also, so I googled how to get function definitions, and I found Get-Command - though this gets only the function body. But it can be used also if the function is coming from elsewhere, like a dot-sourced file. So I came up with the following (hold my naming convention :)), the idea is to re-build the function definitions delimited by newlines:

    Filter Greeting {param ([string]$Greeting) return $Greeting}
    Filter FullName {param ([string]$FirstName, [string]$LastName) return $FirstName + " " + $LastName}
    $ScriptText = ""
    $ScriptText += "Filter Greeting {" + (Get-Command Greeting).Definition + "}`n"
    $ScriptText += "Filter FullName {" + (Get-Command FullName).Definition + "}`n"
    $Job = Start-Job `
                -InitializationScript $([ScriptBlock]::Create($ScriptText)) `
                -ScriptBlock {(Greeting -Greeting "Hello") + " " + (FullName -FirstName "PowerShell" -LastName "Programmer")}
    $Result = $Job | Wait-Job | Receive-Job
    $Result
    $Job | Remove-Job
    
    0 讨论(0)
  • 2020-11-28 00:06

    As @Shay points out, FOO needs to be defined for the job. Another way to do this is to use the -InitializationScript parameter to prepare the session.

    For your example:

    $functions = {
        function FOO { write-host "HEY" }
    }
    
    Start-Job -InitializationScript $functions -ScriptBlock {FOO}|
        Wait-Job| Receive-Job
    

    This can be useful if you want to use the same functions for different jobs.

    0 讨论(0)
提交回复
热议问题