因爲我的僱主不想使用已編譯的軟件,他們要求我創建一個使用PowerShell並行處理一系列設備的GUI。我的PowerShell腳本包含一個窗體和一個按鈕,該窗體用於對設備進行ping操作。爲了防止GUI被鎖定,我使用Runspace將ping分流到一個單獨的線程。我能夠ping通設備並使用來自Runspace的信息更新表單,但是當我完成應用程序時,我無法關閉/處理Runspace,因此即使在應用程序退出後它也會繼續運行。爲什麼我無法處理運行空間?
下面提供的函數ping localhost 10次,並將結果添加到GUI中的ListView中。
Function PingDevices
{
Write-Host "Pinging Devices"
$items = $StorePingInfo_ListView.Items
$ScriptBlock =
{
$a = 0
for(;$a -lt 10; $a++)
{
$PingResult = Test-Connection 127.0.0.1 -Count 1
#[System.Windows.Forms.MessageBox]::Show($PingResult)
$items.Add("Name").SubItems.Add($PingResult)
sleep 1
}
}
$runspace = [RunspaceFactory]::CreateRunspace()
$runspace.Open()
$runspace.SessionStateProxy.SetVariable('Items',$items)
$powershell = [System.Management.Automation.PowerShell]::create()
$powershell.Runspace = $runspace
$powershell.AddScript($ScriptBlock)
$AsyncHandle = $powershell.BeginInvoke()
}
Function CleanupResources
{
#When I try to clean up the resources I get Null errors
Write-Host "AsyncHandle is Null = "($AsyncHandle -eq $null)
$data = $powershell.EndInvoke($AsyncHandle)
$powershell.Dispose()
$runspace.Close()
}
關閉應用程序時,我得到的錯誤是
Pinging Devices AsyncHandle is Null = True You cannot call a method on a null-valued expression. At C:\Users\Loligans\Drive\dboardscript.ps1:673 char:5 + $data = $powershell.EndInvoke($AsyncHandle) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull You cannot call a method on a null-valued expression. At C:\Users\Loligans\Drive\dboardscript.ps1:674 char:5 + $powershell.Dispose() + ~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull You cannot call a method on a null-valued expression. At C:\Users\Loligans\Drive\dboardscript.ps1:675 char:5 + $runspace.Close() + ~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull
我以爲是因爲運行空間在執行問題發生了什麼,但是當它不運行,以及它發生。然而,它沒有誤差地成功關閉,當這一切被連接在同一個函數內這樣
Function PingDevices
{
Write-Host "Pinging Devices"
$items = $StorePingInfo_ListView.Items
$ScriptBlock =
{
$a = 0
for(;$a -lt 10; $a++)
{
$PingResult = Test-Connection 127.0.0.1 -Count 1
#[System.Windows.Forms.MessageBox]::Show($PingResult)
$items.Add("Name").SubItems.Add($PingResult)
sleep 1
}
}
$runspace = [RunspaceFactory]::CreateRunspace()
$runspace.Open()
$runspace.SessionStateProxy.SetVariable('Items',$items)
$powershell = [System.Management.Automation.PowerShell]::create()
$powershell.Runspace = $runspace
$powershell.AddScript($ScriptBlock)
$AsyncHandle = $powershell.BeginInvoke()
$data = $powershell.EndInvoke($AsyncHandle)
$powershell.Dispose()
$runspace.Close()
}
我怎樣才能運行空間來釋放它駐留在同一功能之外的所有資源?
通過在同一個類中使用'System.Net.NetworkInformation.SendAsync'和'PingCompleted'事件,您可以完全擺脫替代運行空間。 –