我在PowerShell运行空间上做了很多工作,我知道可以使用WPF对象中的调度程序在另一个运行空间中调用命令。
我这样创建我的运行空间:
$global:A = [hashtable]::Synchronized(@{})
$global:initialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
# Add some functions to the ISS
$GuiRunspace =[runspacefactory]::CreateRunspace($initialSessionState)
$GuiRunspace.ApartmentState = "STA"
$GuiRunspace.Open()
$GuiRunspace.SessionStateProxy.SetVariable("A",$A)
$GuiRunspace.SessionStateProxy.SetVariable("B",$B)
$GuiRunspace.Name = "GuiRunspace"
$Gui = [powershell]::Create()
[void]$Gui.addscript($GUILayerScript)
$Gui.Runspace = $GuiRunspace
$GuiThread = $Gui.beginInvoke()
使用以下代码,我可以从其他运行空间中操纵该运行空间:
$A.Window.Dispatcher.invoke({ *Do some crazy stuff that has nothing to do with the object from which you called the dispatcher* })
这仅是因为window是具有dispatcher property的WPF对象。
问题是,如何在没有WPF分发程序的情况下在其他运行空间 中调用命令?
答案 0 :(得分:0)
如果要在主执行上下文和单独的运行空间或运行空间池之间共享状态,请使用SessionStateProxy
变量并分配同步的集合或字典:
$sharedData = [hashtable]::Synchronized(@{})
$rs = [runspacefactory]::CreateRunspace()
$rs.Open()
$rs.SessionStateProxy.SetVariable('sharedData',$sharedData)
$sharedData
变量现在在调用运行空间和$rs
内部都引用相同的同步哈希表
下面是关于如何使用运行空间的基本说明
您可以将运行空间附加到Runspace
对象的PowerShell
属性,它将在该运行空间中执行:
$rs = [runspacefactory]::CreateNewRunspace()
$rs.Open()
$ps = { Get-Random }.GetPowerShell()
$ps.Runspace = $rs
$result = $ps.Invoke()
您还可以将RunspacePool
分配给多个PowerShell
实例并使其并发执行:
# Create a runspace pool
$rsPool = [runspacefactory]::CreateRunspacePool()
$rsPool.Open()
# Create and invoke bunch of "jobs"
$psInstances = 1..10 |ForEach-Object {
$ps = {Get-Random}.GetPowerShell()
$ps.RunspacePool = $rsPool
[pscustomobject]@{
ResultHandle = $ps.BeginInvoke()
Instance = $ps
}
}
# Do other stuff here
# Wait for the "jobs" to finish
do{
Start-Sleep -MilliSeconds 100
} while(@($psInstances.ResultHandle.IsCompleted -eq $false).Count -gt 0)
# Time to collect our results
$results = $psInstances |ForEach-Object {
if($_.Instance.HadErrors){
# Inspect $_.Instance.Streams.Error in here
}
else {
# Retrieve results
$_.Instance.EndInvoke($_.ResultHandle)
}
}