2010-11-24 33 views
1

J'ai une console C# qui démarre dans 'static int Main (string [] args)', crée une instance de la classe 'EventRecievedProcessor', puis appelle une méthode l'instance:System.NullReferenceException n'étant pas coincé dans le premier bloc try/catch

static int Main(string[] args) 
{ 
    try 
    { 
     EventRecievedProcessor proc = new EventRecievedProcessor 

     if (!proc.Processs()) 
     { 
      Console.Write(Type + " processing failed. Please check logs for more information."); 
      Log.Error("Failed to process s"); 
      return (int)RETURNCODES.INTERNALAPPERROR; 
     } 
    } 
    catch (Exception ex) 
    { 
     // This is where the System.NullReferenceException from GetLatestEventInfo is currently being caught 

     Console.WriteLine("Exception message: " + ex.Message); 
     Console.WriteLine("Exception stack trace: " + ex.StackTrace); 

     Log.Fatal("An exception has been thrown. Message: " + ex.Message, ex); 

     return (int)RETURNCODES.INTERNALAPPERROR; 
    } 
} 

l'instance de 'EventRecievedProcessor' saisit une collection de disques et fait un foreach dessus. Il appelle une méthode statique (GetLatestEventInfo) sur la classe « événement » pour chaque enregistrement de la collection:

public class EventRecievedProcessor 
{ 

    public bool Processs() 
    { 
     List<Event> events = DAL.GetEvents; 

     foreach (Event e in events) 
     { 
      try 
      { 
       EventInfo lastEvent = Eventhistory.GetLatestEventInfo(e); 
      } 
      catch (Exception ex) 
      { 
       // Log exception and continue processing in foreach loop 

       // This is where I want to catch the NullReferenceException from GetLatestEventInfo 

       Log.DebugFormat("Error with eventid " + e.EventID); 
       Log.Error(ex); 
      } 
     } 

     return true; 
    } 
} 

Lorsque la méthode follwoing est appelée, un System.NullReferenceException est jeté:

public class EventHistory 
{ 

    public static EventInfo GetLatestEventInfo(int customerCode, string premiscode) 
    { 

     EventInfo info = new EventInfo(); 

     // Do some work here... 
     // This is where the NullReferenceException is being generated. 

     return info; 

    } 
} 

Lorsque le NullReferenceException est levé ici, je m'attendrais à ce que le bloc catch de la boucle foreach l'attrape, l'enregistre, puis renvoie le contrôle à la boucle foreach pour continuer le traitement. Au lieu de cela, l'exception est interceptée dans la méthode "Main" de niveau supérieur, ce qui signifie que l'application abandonne et que les enregistrements restants ne sont pas traités.

Je ne sais pas comment/pourquoi l'exception contourne le premier bloc catch. Des idées sur ce que je fais mal ici?

Ajout de la trace de pile:

System.NullReferenceException: objet de référence non définie à une instance d'un objet. à EventProcessor.EventHistory.GetLatestEventInfo (événement e) dans C: \ Dev \ release6.01.100 \ Events \ EventProcessor \ EventProcessor \ EventHistory.cs: ligne 65 à EventProcessor.Processors.EventProcessor.Process() dans C: \ Dev \ release6.01.100 \ Events \ EventProcessor \ EventProcessor \ Processeurs \ EventProcessor.cs: ligne 32 à EventProcessor.Program.Main (String [] args) dans C: \ Dev \ release6.01.100 \ Events \ EventProcessor \ EventProcessor \ Program.cs : ligne 132

Désolé si j'ai grignoté certains des noms. C'est du code de travail, j'ai donc essayé de le changer un peu pour éviter tout conflit de confidentialité.

+0

Pourriez-vous nous montrer la pile trace de quand l'exception est affichée? –

+0

Vous appelez la méthode statique 'Event.GetLatestEventInfo' et vous nous montrez la source de' EventHistory.GetLatestEventInfo' (provenant d'une autre classe). Est-ce une faute de frappe ou devrait-il être comme ça? – NOtherDev

+0

Avez-vous vérifié que l'appel à GetLatestEventInfo déclenche l'exception (en regardant la piletrace?). Peut-être que DAL.GetEvents appelle aussi GetlatestEventInfo? –

Répondre

2

Il ne passe rien. Regardez de près votre trace de pile. Utilisez Console.WriteLine(ex.ToString());. Vous verrez que l'exception n'est pas lancée d'où vous pensiez que c'était.

+0

Merci pour les commentaires Jon. Pourriez-vous développer un peu votre point de vue? La trace de pile identifie EventHistory.GetLatestEventInfo() comme source de l'exception. – rgeorge

+0

La source de l'exception est _inside_ de 'EventHistory.GetLatestEventInfo()', où vous n'avez pas de bloc try/catch. –

+0

Correct. Donc je m'attendais à ce que l'exception atteigne le code appelant, qui est dans un bloc try/catch? – rgeorge

0

C'est tout simplement pas le cas et voici la preuve:

class Program 
{ 
    static void Main() 
    { 
     // no need of try/catch here as exceptions won't propagate to here 
     Looper(); 
    } 

    static void Looper() 
    { 
     int processedRecords = 0; 
     for (int i = 0; i < 10; i++) 
     { 
      try 
      { 
       Thrower(i); 
       processedRecords++; 
      } 
      catch (NullReferenceException ex) 
      { } 
     } 
     // prints 5 as expected 
     Console.WriteLine("processed {0} records", processedRecords); 
    } 

    static void Thrower(int i) 
    { 
     if (i % 2 == 0) 
     { 
      throw new NullReferenceException(); 
     } 
    } 
}