Powershell:在Try / Catch块

时间:2018-06-09 22:57:46

标签: .net multithreading powershell powershell-v4.0

我的任务是执行大约50-60种可能设备的反向DNS查找。在任何情况下都不会抛出聚合异常。

如果你只是通过控制台输出(没有红色文本),我似乎工作,但仍然可以在$ Error变量中找到异常。

到目前为止,我还没有找到在PowerShell中使用Handle方法的示例。

我要从以下链接中获取示例,但我对C#或VB不是很熟悉。我可能在转换为PowerShell时遇到问题。

https://msdn.microsoft.com/en-us/library/system.aggregateexception.handle(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-3

我想知道的是......我哪里出错了,或者实际处理了异常?

以下是应该证明我窘境的原因的代码。它将创建一个由3个异步反向DNS查找组成的任务,该任务应该失败。调用WaitAll应该产生预期的聚合异常并且似乎被处理,但仍然在$ Error中观察到。

$Task = @('testComp1','testComp2','testComp3') | ForEach-Object {
    [pscustomobject]@{
        Computername = $_
        Task = [System.Net.DNS]::GetHostAddressesAsync($_)
    }
}

try
{
    [Void][Threading.Tasks.Task]::WaitAll($Task.Task)
}

catch [System.AggregateException]
{
    $_.Exception.Handle({
        param($ex)

        if ( $ex.GetType().Name -eq 'SocketException' ) {
            Write-Host 'Expected SocketException'
            return $true
        } else {
            return $false
        }
    })
}

$Error[0]

1 个答案:

答案 0 :(得分:0)

$Error无关。

Handle方法就像AggregateException中的例外过滤器一样 谓词返回false的异常结束于将被抛出的新AggregateException

请参阅Source上的评论。

  

每次调用谓词都会返回true或false来指示   是否处理了异常。在所有调用之后,如果有的话   异常未处理,所有未处理的异常将被放入   新抛出的AggregateException。

示例。

下面的AggregateException包含DivideByZeroExceptionIndexOutOfRangeException被抛出。
请注意,第一个catch块显示了2个内部异常(#0和#1) 只处理IndexOutOfRangeException

这会导致新的AggregateException被抛出,但这次只包含DivideByZeroException。 请注意,第二个catch块仅显示1个内部异常。

try
{
    try
    {
        $divideByZeroException = (New-Object -TypeName System.DivideByZeroException)
        $indexOutOfRangeException = (New-Object -TypeName System.IndexOutOfRangeException)
        throw (New-Object -TypeName System.AggregateException -ArgumentList $divideByZeroException,$indexOutOfRangeException)
    }
    catch [System.AggregateException]
    {        
        $_.Exception.ToString() | out-host

        # System.AggregateException: One or more errors occurred. ---> System.DivideByZeroException: Attempted to divide by zero.
        # --- End of inner exception stack trace ---
        # ---> (Inner Exception #0) System.DivideByZeroException: Attempted to divide by zero.<---
        # ---> (Inner Exception #1) System.IndexOutOfRangeException: Index was outside the bounds of the array.<---

        $_.Exception.Handle({
            param($ex)

            if ($ex.GetType().Name -eq 'IndexOutOfRangeException' ) {                
                return $true
            } else {             
                return $false
            }
        })
    }
}
catch [System.AggregateException]
{    
    $_.Exception.ToString() | out-host

    # System.AggregateException: One or more errors occurred. --->         System.DivideByZeroException: Attempted to divide by zero.
    # --- End of inner exception stack trace ---
    #  at System.AggregateException.Handle(Func`2 predicate)
    #   at CallSite.Target(Closure , CallSite , Object , ScriptBlock )
    #---> (Inner Exception #0) System.DivideByZeroException: Attempted to divide by zero.<---
}