C#多线程控制台运行时错误

时间:2013-12-18 16:17:19

标签: c# .net multithreading console

我有一个Console应用程序,它使用parallel.foreach生成许多工作线程来执行某些任务,例如

  1. 通过我们内联网中的许多服务器通过SNMP读取操作系统数据
  2. 将这些值写入SQL Server DB。
  3. 当我在调试或发布模式下在Visual Studio 2010中运行代码时,程序无异常地执行。当我部署程序并在VS外部运行时,我得到一个例外(.NET Runtime Exceptiopn)。

    堆栈追踪:

      

    应用程序:ServerMonitorSNMP.exe Framework版本:v4.0.30319描述:由于未处理的异常,进程已终止。异常信息:System.AggregateException Stack:at System.Threading.Tasks.Parallel.ForWorker [[System .__ Canon,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]](Int32,Int32,System.Threading。 Tasks.ParallelOptions,System.Action`1,

         

    ...

         

    在ServerMonitoringSNMP.Program.Main(System.String [])

    AggregateException详细信息为:

      

    System.UnhandledExceptionEventArgs   System.AggregateException:发生一个或多个错误。 ---> System.InvalidOperationException:超时已过期。从池中获取连接之前经过的超时时间。这可能是因为所有池连接都在使用中并且达到了最大池大小。

         

    ...

         

    (内部异常#0)System.InvalidOperationException:超时已过期。从池中获取连接之前经过的超时时间。这可能是因为所有池连接都在使用中并且达到了最大池大小。

         

    ...

         

    (内部异常#1)System.InvalidOperationException:超时已过期。从池中获取连接之前经过的超时时间。这可能是因为所有池连接都在使用中并且达到了最大池大小。

         

    ...

         

    (内部异常#2)System.InvalidOperationException:超时已过期。从池中获取连接之前经过的超时时间。这可能是因为所有池连接都在使用中并且达到了最大池大小。

         

    ...

         

    System.AggregateException:发生了一个或多个错误。 ---> System.NullReferenceException:未将对象引用设置为对象的实例。      在\ Program.cs中的ServerMonitoringSNMP.Program.GetStorageValue(Dictionary`2 StorageQuery,Int32 diskOidIndex):第896行

2 个答案:

答案 0 :(得分:2)

这是未处理的aggregate exception。您将需要捕获此类错误,循环遍历其异常并记录每个异常以确定正在发生的事情。

您可能没有在调试例程中打破这些类型的异常。

打开所有异常中断(调试,异常)或( CTRL + ALT + E )并重新运行程序。 /> 这将首先抛出原始异常。

Catch code:

catch (AggregateException e)
{
    foreach (var ex in e.InnerExceptions)
    {
       //log here
    }
}

答案 1 :(得分:2)

附加的异常太抽象了。最好的方法是处理TPL异常和日志。当你这样做时,事情会更清楚。然后你可以用适当的例外更新帖子。

例如:

      try
        {
            YourSNMPTrapSenderMethod();
        }
       catch (AggregateException ae)
        {
            // This is where you can choose which exceptions to handle. 
            foreach (var ex in ae.InnerExceptions)
            {
               // log your exception. may be in temp directory
            }
        }

        try
        {
            YourSNMPTrapSenderMethod();
        }
        catch (AggregateException ex)
        {
            ex.Handle((x) =>
            {
                Log.Write(x);
                return true;
            });
        }


   static void YourSNMPTrapSenderMethod()
    {
        var exceptions = new ConcurrentQueue<Exception>();
        Parallel.ForEach(data, d =>
        {
            try
            {
              //do your operations
            }

            catch (Exception e) { exceptions.Enqueue(e); }
        });


        if (exceptions.Count > 0) throw new AggregateException(exceptions);
    }