2013-11-22 15 views
7

Facendo un analisi del codice mi ha dato voce CA2200:lanciare e mantenere traccia dello stack non come previsto come descritto da analisi del codice

CA2200 rigenerare per preservare i dettagli dello stack 'func()' genera un errore eccezione catturata e specifica in modo esplicito come argomento. Utilizzare invece "throw" senza argomento per preservare la posizione dello stack in cui inizialmente veniva sollevata l'eccezione.

Ho implementato il suggerimento, ma mi sembra di ottenere la stessa traccia di stack a prescindere.

Ecco il mio codice e uscita di test (lo spazio bianco è destinato a dare i numeri di linea ovvie):

errore previsto alla Line 30

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace throw_test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      try 
      { 
       try 
       { 


        // line 22 below 
        throw new Exception(); 
       } 
       catch (Exception ex) // DEFINES AND THROWS 'ex' 
       { 



        // line 30 below 
        throw ex; 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.Write(ex.StackTrace); 
      } 

      Console.Read(); 
     } 
    } 
} 

uscita

in throw_test.Program.Main (String [] args) in c: \ Users \ Richard \ Documents \ Visual Studio 2013 \ Projects \ using_throw_close streaming \ using_throw_closestream \ Program.cs: linea 30

errore previsto alla linea 22

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace throw_test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      try 
      { 
       try 
       { 


        // line 22 below 
        throw new Exception(); 
       } 
       catch (Exception) // NO 'ex' 
       { 



        // line 30 below 
        throw; 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.Write(ex.StackTrace); 
      } 

      Console.Read(); 
     } 
    } 
} 

uscita

a throw_test.Program.Main (String [ ] args) in c: \ Users \ Richard \ Documents \ Visual Studio 2013 \ Projects \ using_throw_closestream \ using_throw_closestream \ Program.cs: riga 30

Lo stesso risultato.

La mia domanda

Con other such questions suggerendo metodi più complessi o espliciti per conservare la traccia dello stack, perché il suggerimento di analisi del codice mi chiedono di fare qualcosa che sembra non funzionare?

Se questo suggerimento è in realtà corretto, cosa sto sbagliando?

+0

si desidera comunque rilevare l'eccezione, non lanciare il messaggio – PatFromCanada

+1

La mia domanda ha più a che fare con il motivo per cui il suggerimento sembra essere sbagliato, piuttosto che sul ripensarci o meno. – rhughes

+2

Penso che il suggerimento sia rilevante solo quando lanci e prendi più metodi. Quindi il metodo A tira, i metodi B prendono e si rilancia. Se B lancia "ex", lo stackstrace inizierà da B, se invece "lancia" inizierà da A. – Mark

risposta

5

Il segno sopra è corretto.

La traccia di stack viene conservata solo quando generata da un altro metodo.

L'analisi dello stack qui saranno conservati includendo l'errore originale è gettato dal Method()

Il codice seguente illustra questo:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace throw_test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      try 
      { 
       try 
       { 


        // line 22 below 
        Method(); 
       } 
       catch (Exception ex) 
       { 



        // line 30 below 
        throw; 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.Write(ex.StackTrace); 
      } 

      Console.Read(); 
     } 

     public static void Method() 
     { 
      throw new Exception(); 
     } 
    } 
} 

uscita

a throw_test.Program.Method() in c: \ Users \ Richard \ Documents \ Visual Studio 2013 \ Projects \ using_throw_closestream \ using_throw_closestream \ Program.cs: riga 43 in throw_test.Program.Main (String [] args) in c: \ Users \ Richard \ Documents \ visual Studio 2013 \ Projects \ using_throw_closestream \ using_throw_closestream \ Program.cs: linea 30

6

Se si utilizza Net 4.5, è possibile utilizzare ExceptionDispatchInfo.Capture(ex).Throw(); e si otterrà un bel traccia dello stack tra cui la linea 22 e la linea 30.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.ExceptionServices; 
using System.Text; 
using System.Threading.Tasks; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      try 
      { 
       try 
       { 


        // line 22 below 
        throw new Exception(); 
       } 
       catch (Exception ex) // NO 'ex' 
       { 



        // line 30 below 
        ExceptionDispatchInfo.Capture(ex).Throw(); 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.Write(ex.StackTrace); 
      } 

      Console.Read(); 
     } 
    } 
} 

uscita

at ConsoleApplication1.Program.Main(String[] args) in c:\ConsoleApplication1\Program.cs:line 22 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at ConsoleApplication1.Program.Main(String[] args) in c:\ConsoleApplication1\Program.cs:line 30 
1

In C# 6.0 è possibile utilizzare i filtri delle eccezioni per eseguire alcune operazioni logiche (ad esempio la registrazione) senza necessità di rethrow esplicito, ovviamente manterrà la traccia dello stack.

La descrizione può essere trovata nella sezione Filtri d'eccezione here. Dice:

E 'anche una forma comune e accettata di “abuso”, per usare eccezione filtri per effetti collaterali; per esempio. registrazione. Possono ispezionare un'eccezione "che vola" senza intercettare il suo corso. In questi casi, il filtro sarà spesso una chiamata a una funzione di supporto di ritorno falso che esegue gli effetti collaterali.