首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在PowerShell作业中使用本地函数

在PowerShell作业中使用本地函数
EN

Stack Overflow用户
提问于 2020-10-26 19:40:39
回答 1查看 285关注 0票数 2

我正在编写自定义cmdlet来执行任务。其中一个cmdlet依赖于其他cmdlet,需要很长时间,所以我想在作业中执行该任务。猜猜发生了什么,你不能,因为其他cmdlet在该Job的作用域内不可用。为什么?像C++,Java,C#这样的其他语言允许你在相同的范围内使用变量,对象,函数,为什么在PowerShell中没有呢?为什么它会如此解耦?我觉得这让开发人员更难了。也许我不明白这个主题,但我想做这样的事情:

代码语言:javascript
复制
function Write-Yes {
    Write-Host "yes"
}

function Write-No {
    Write-Host "no"
}

function Write-Random {
    $result = @($true, $false) | Get-Random
    if ($result) {
        Write-Yes
    }
    else {
        Write-No
    }
}

Start-Job -ScriptBlock { Write-Random }

这是不可能的。你必须做一些技巧,比如提供函数的scriptblock作为参数,并使用调用运算符或类似的东西调用它。甚至,使用Import-Module重新导入您正在使用的同一文件。这感觉太复杂了。我看到的唯一能够做这样事情的模块是PoshRSJob,它允许你命名将在作业中使用的cmdlet,它将动态地为你创建它们,通过一些词法解析,再一次,过于复杂的事情。

为什么事情是这样的,有没有办法以优雅的方式做我在示例中尝试的事情?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-26 21:56:33

Start-Job是非常有限和缓慢的。它的实现非常糟糕,imho,我从未使用过它。您可以使用runspaces进行快速和轻量级的“后台作业”,并从当前会话导入函数和变量。

示例:

代码语言:javascript
复制
function Write-Yes { "yes" }

function Write-No { "no" }

function Write-Random {
    if ($true, $false | Get-Random) {
        Write-Yes
    }
    else {
        Write-No
    }
}

# setup session and import functions
$session = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
"Write-Yes", "Write-No", "Write-Random" | foreach {
    $session.Commands.Add((
        New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry $_, (Get-Content "Function:\$_")
    ))
}

# setup separate powershell instance
$job = [Powershell]::Create($session)
[void]$job.AddScript({ Write-Random })

# start async
$asyncResult = $job.BeginInvoke()

# do stuff ...

# wait for completion
$job.EndInvoke($asyncResult)
$job.Dispose()

但一般而言,Powershell不是为复杂的并行处理而设计的。一般来说,最好将所有内容都放在一个脚本文件中,并将其作为任务或后台作业等运行。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64536409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档