为了账号安全,请及时绑定邮箱和手机立即绑定

用于提高状态行性能的 Powershell 作业

用于提高状态行性能的 Powershell 作业

C#
HUH函数 2022-12-24 10:14:34
我正在开发自定义 powershell 状态线,并实现了一些很酷的功能:电池监控、wifi 监控等。不幸的是,这些更新往往很慢,因为它们需要调用 Get-NetAdapterStatistics、获取 wmi 对象和其他非常缓慢的通话。我正在尝试通过 start-job 生成子进程以允许后台轮询和更新共享变量,但无法弄清楚如何执行此操作。我找到的最好的替代品是一种 IPC(如此处所述:两个单独的 Powershell 进程之间的管道传输),但如果可能的话,我更愿意坚持使用传统的共享变量。有没有办法做到这一点?我发现的最佳替代方法是将变量作为参数传递,但这不允许进行轮询。免责声明,我知道这并不是 powershell 的真正设计目的,但我仍然想知道这是否可能。或者是编写将返回状态行的 ac/c++ 二进制文件的最佳选择?写入文件(这看起来可能很慢)?如果可以,或者如果您需要更多信息,请告诉我什么可能有效。谢谢你。更多信息:Start-Job -Name testJob -Script {        $testVar = "asdf"}Write-Host $testVar# should output asdf有什么办法吗?我正在尝试做一些工作并返回一个变量。这怎么可能?我发现的唯一可能方法是:写文件到磁盘,有点慢使用 IPC 管道:最大的缺点是它有点小故障。最重要的是,当我关闭 powershell 窗口(因为这是一个状态行)时,我不知道如何关闭 IPC 管道,我最终得到一个“管道泄漏”,导致高 cpu 使用率和运行的 powershell 进程的背景。这至少不是直接写入文件的后台作业的情况。显然,当最后一个引用被删除时,管道应该关闭,但后台作业在它打开的情况下继续运行。这是因为 powershell 会话在等待与管道相关的内容(等待管道连接、完成写一行等)时将挂起到无法按 ctrl-c'd 的位置。谢谢,如果我可以添加更多信息,请告诉我。更新:我试过基本上使用空文件作为控制标志(我认为这比为每个设置解析一个文件要快),但我正在尝试使用一个作业来返回 VCS 信息(这会更容易返回,并且快点)。关于如何解决这个问题的任何想法?我很难过。注意:我标记这个 C# 是因为 powershell 使用 C# 的管道函数,我希望有这方面知识的人能够提供帮助。
查看完整描述

1 回答

?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

Boe Prox多年前就此做了一篇出色的文章。他还使用PoshRSJob模块对此进行了扩展。使用这个模块可以很容易地处理这个问题。

#Create a synchronized hashtable

$sync = [hashtable]::Synchronized(@{

    Time = ''

    Stop = $false

    Updater = ''

})

#create 5 RSJobs

1..5 | Start-RSJob -ScriptBlock {

    param($sync) #accept $sync as a param

    $updater = [Guid]::NewGuid() #unique id per job

    while(-not $sync.Stop) { #run until told not to

        $sync.Time = Get-Date

        $sync.Updater = $updater

        start-sleep -Seconds 1

    }

} -ArgumentList $sync #pass $sync as a param

运行这个会产生 5 个工作:


Id       Name                 State           HasMoreData  HasErrors    Command

--       ----                 -----           -----------  ---------    -------

1        Job1                 Running         False        False        ...

2        Job2                 Running         False        False        ...

3        Job3                 Running         False        False        ...

4        Job4                 Running         False        False        ...

5        Job5                 Running         False        False        ...

然后您可以检查父进程中的 $sync 并看到它不断地从这些作业中更新。请注意,这些不仅仅是字符串表示,而是完整的对象。


PS C:\> $sync


Name     Value

----     -----

Time     4/22/2019 11:58:35 AM

Stop     False

Updater  9ab28c51-2941-4866-a064-165b1ceca673


PS C:\> $sync


Name     Value

----     -----

Time     4/22/2019 11:58:37 AM

Stop     False

Updater  113e78a8-1774-4cdf-9638-7235109f0a0d

终止我们设置的作业$sync.Stop = $true


PS C:\> Get-RSJob


Id       Name                 State           HasMoreData  HasErrors    Command

--       ----                 -----           -----------  ---------    -------

1        Job1                 Completed       False        False        ...

2        Job2                 Completed       False        False        ...

3        Job3                 Completed       False        False        ...

4        Job4                 Completed       False        False        ...

5        Job5                 Completed       False        False        ...


查看完整回答
反对 回复 2022-12-24
  • 1 回答
  • 0 关注
  • 87 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信