C#遇到的坑:Parallel并行引用异步方法的异常处理

自定义了个获取SNMP节点值的方法,打算采用Parallel ForEach从有多个节点的列表中并行获取这些节点的值。在获取SNMP节点值的方法未采用异步方法时,程序运行正常。但是当尝试将获取SNMP节点值的方法改为异步方法后,虽然在此方法中做了异常处理,但是系统仍然报出未处理的异常。详情如下:

以下是GetSnmpValue方法中的关键语句,其中做了异常捕获。

//获取SNMP值的关键语句:

SnmpV1Packet result = null;
try
{
    result = (SnmpV1Packet)target.Request(pdu, param);            
}
catch (Exception ex)
{
   MainLog($"获取SNMP值失败:{ex}", LogType.Error); 
}

在如下并行同步调用此方法时,可正常处理异常。

//同步调用GetSnmpValue方法
try
{
    Parallel.ForEach(oidList, new ParallelOptions { CancellationToken = token }, async tuple =>
    {
        // 获取Item1 IP地址的Item2节点的SNMP值
        string OV = GetSnmpValue(tuple.Item1, tuple.Item2, getCommunity);
    });
        //其他相关处理
}
catch (Exception ex)
{
    //在日志框里打印异常信息
    MainLog($"获取SNMP值异常:{ex}", LogType.Error);
}

但在如下采用await Task.Run异步调用此方法时,GetSnmpValue方法中仍然报出未处理的异常,例如当目标IP不通时,显示达到最大尝试获取的次数,报出未处理的异常中断程序。

//异步调用GetSnmpValueAsync方法
try
{
    Parallel.ForEach(oidList, new ParallelOptions { CancellationToken = token }, async tuple =>
    {
        // 获取Item1 IP地址的Item2节点的SNMP值
        string OV = await Task.Run(() => GetSnmpValueAsync(tuple.Item1, tuple.Item2, getCommunity));
    });
        //其他相关处理
}
catch (Exception ex)
{
    //在日志框里打印异常信息
    MainLog($"获取SNMP值异常:{ex}", LogType.Error);
}

明明在原方法和并行方法中都做了异常处理,为什么获取不到异常呢?始终找不到原因,做了各种尝试,才总结出来,其实主要原因还是出在Parallel方法的异常处理方式上。Parallel方法需要采用AggregateException而不是普通的Exception来获取Parallel并行过程中所有引发的的异常。如下修改后即可正常捕获异常。而且还要注意:不能在原方法中throw异常,否则在throw位置会报出未处理的异常。

//异步调用GetSnmpValueAsync方法
try
{
    Parallel.ForEach(oidList, new ParallelOptions { CancellationToken = token }, async tuple =>
    {
        // 获取Item1 IP地址的Item2节点的SNMP值
        string OV = await Task.Run(() => GetSnmpValueAsync(tuple.Item1, tuple.Item2, getCommunity));
    });
        //其他相关处理
}
catch (AggregateException ex)
{
    //在日志框里打印异常信息
    MainLog($"获取SNMP值异常:{ex}", LogType.Error);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值