【发布时间】:2014-06-10 14:09:42
【问题描述】:
我有一堆不同的脚本,它们使用一个通用的 Powershell 库(自定义 PS 函数和 c# 类的组合)。脚本会定期自动执行。当每个脚本加载时,它会使用相当多的 CPU 来导入自定义模块。当所有脚本同时启动时,服务器的 CPU 以 100% 运行... 有没有办法只导入一次模块? 在这种情况下,所有脚本都由 Windows 服务执行。
【问题讨论】:
标签: c# windows powershell
我有一堆不同的脚本,它们使用一个通用的 Powershell 库(自定义 PS 函数和 c# 类的组合)。脚本会定期自动执行。当每个脚本加载时,它会使用相当多的 CPU 来导入自定义模块。当所有脚本同时启动时,服务器的 CPU 以 100% 运行... 有没有办法只导入一次模块? 在这种情况下,所有脚本都由 Windows 服务执行。
【问题讨论】:
标签: c# windows powershell
您还可以将模块一次加载到运行空间池中,然后将池传递给多个 powershell 实例。有关更多详细信息,请参阅 InitialSessionState 和 RunspacePool 类。示例:
#create a default sessionstate
$iss = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
#create a runspace pool with 10 threads and the initialsessionstate we created, adjust as needed
$pool = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspacePool(1, 10, $iss, $Host)
#Import the module - This method takes a string array if you need multiple modules
#The ImportPSModulesFromPath method may be more appropriate depending on your situation
$pool.InitialSessionState.ImportPSModule("NameOfYourModule")
#the module(s) will be loaded once when the runspacepool is loaded
$pool.Open()
#create a powershell instance
$ps= [System.Management.Automation.PowerShell]::Create()
#Add a scriptblock - See http://msdn.microsoft.com/en-us/library/system.management.automation.powershell_members%28v=vs.85%29.aspx
# for other methods for parameters,arguments etc.
$ps.AddScript({SomeScriptBlockThatRequiresYourModule})
#assign the runspacepool
$ps.RunspacePool = $pool
#begin an asynchronous invoke - See http://msdn.microsoft.com/en-us/library/system.management.automation.powershell_members%28v=vs.85%29.aspx
$iar = $ps.BeginInvoke()
#wait for script to complete - you should probably implement a timeout here as well
do{Start-Sleep -Milliseconds 250}while(-not $iar.IsCompleted)
#get results
$ps.EndInvoke($iar)
【讨论】:
如果它以相当短的时间间隔运行,最好加载一次,让它驻留,然后进入睡眠/进程/睡眠循环。
【讨论】: