将变量传递给运行空间并返回

时间:2016-04-05 18:16:50

标签: powershell

所以我有以下代码:

#region Initialize stuff
$files = gci "C:\logs\*.log"
$result = [System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList))

$RunspaceCollection = @()
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1,5)
$RunspacePool.Open()

$ScriptBlock = {
    Param($file, $result)
    $content = Get-Content $file.FullName -ReadCount 0
    foreach ($line in $content) {
        if ($line -match 'A002') {
        [void]$result.Add($($line -replace ' +',","))
}}}
#endregion

#region Process Data
Foreach ($file in $files) {
    $Powershell = [PowerShell]::Create().AddScript($ScriptBlock).AddArgument($file).AddArgument($result)
    $Powershell.RunspacePool = $RunspacePool
    [Collections.Arraylist]$RunspaceCollection += New-Object -TypeName PSObject -Property @{
        Runspace = $PowerShell.BeginInvoke()
        PowerShell = $PowerShell  
}}

While($RunspaceCollection) {
    Foreach ($Runspace in $RunspaceCollection.ToArray()) {
        If ($Runspace.Runspace.IsCompleted) {
            [void]$result.Add($Runspace.PowerShell.EndInvoke($Runspace.Runspace))
            $Runspace.PowerShell.Dispose()
            $RunspaceCollection.Remove($Runspace)
}}}
#endregion

#region Parse Data
$data = ConvertFrom-Csv -InputObject $result -Header "1","2","3","TimeIn","TimeOut","4","5","Dur"
foreach ($line in $data) {
    if ($line.TimeIn -match "A002") { $TimeIn += [timespan]::Parse($line.Dur) }
    else { $TimeOut += [timespan]::Parse($line.Dur) }}
#endregion

它有效,但我不完全明白如何;) 什么是[System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList))以及为什么它可以工作,而常规的ArrayList却没有?为什么我需要这个“同步”及其功能?能否请您解释或指点我的一些材料?我似乎找不到任何相关的东西。谢谢!

1 个答案:

答案 0 :(得分:1)

  

为了保证ArrayList的线程安全,所有操作都必须   通过这个包装器来完成。

     

通过集合枚举本质上不是线程安全的   程序。即使集合是同步的,其他线程也可以   仍然修改集合,这会导致枚举器抛出一个   例外。为了在枚举期间保证线程安全,您可以   要么在整个枚举过程中锁定集合,要么抓住它   由其他线程所做的更改导致的异常。

来源:

https://msdn.microsoft.com/en-us/library/3azh197k(v=vs.110).aspx

这是通过谷歌搜索找到的

  

ArrayList同步方法

了解面向对象脚本/编程的基础知识对您来说是最有益的,因此将来您可以确切地知道要查找的内容。有许多方法可以在PowerShell主机中实现.NET命名空间,类,方法和元素,[System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList))就是其中之一。