2010-04-02 6 views
2

J'ai une exception StackOverflowException dans une de mes fonctions DB que je ne sais pas comment gérer. J'ai une base de données SQLite avec une table "tblEmployees" qui contient des enregistrements pour chaque employés (plusieurs milliers de messages) et généralement cette fonction fonctionne sans aucun problème. Mais parfois après que la fonction est appelée mille fois, elle casse avec une exception StackOverflowException à la ligne "ReturnTable.Load (reader)" avec le message: Une exception non gérée de type "System.StackOverflowException" s'est produite dans System.Data .SQLite.dllStackOverflow dans VB.NET Requête SQLite

Si je redémarre l'application, il n'y a aucun problème à continuer avec exactement le même post sur lequel il s'est écrasé pour la dernière fois. Je peux également faire exactement le même DB appel de SQLite Admin au moment de l'accident sans problèmes.

Voici le code:

Public Function GetNextEmployeeInQueue() As String 
    Dim NextEmployeeInQueue As String = Nothing 
    Dim query As [String] = "SELECT FirstName FROM tblEmployees WHERE Checked=0 LIMIT 1;" 
    Try 
     Dim ReturnTable As New DataTable() 
     Dim mycommand As New SQLiteCommand(cnn) 
     mycommand.CommandText = query 
     Dim reader As SQLiteDataReader = mycommand.ExecuteReader() 
     ReturnTable.Load(reader) 
     reader.Close() 
     If ReturnTable.Rows.Count > 0 Then 
      NextEmployeeInQueue = ReturnTable.Rows(0)("FirstName").ToString() 
     Else 
      MsgBox("No more employees found in queue") 
     End If 
    Catch fail As Exception 
     MessageBox.Show("Error: " & fail.Message.ToString()) 
    End Try 
    If NextEmployeeInQueue IsNot Nothing Then 
     Return NextEmployeeInQueue 
    Else 
     Return "No more records in queue" 
    End If 
End Function 

Lors d'un plantage, le lecteur a "évaluation de la propriété a échoué." dans toutes les valeurs.

Je suppose qu'il y a un problème avec la mémoire allouée qui n'est pas libérée correctement, mais ne peut pas comprendre de quel objet il s'agit. La connexion DB s'ouvre lorsque l'objet DB-class est créé et se ferme sur le formulaire principal Dispose.

Devrais-je jeter l'objet mycommand à chaque fois dans un bloc finally? Mais cela ne se traduirait-il pas par une connexion DB fermée?

+0

Pourriez-vous poster la trace de pile que vous obtenez? Je peux imaginer que ce sera très long avec beaucoup de lignes presque identiques. Alors postez le début, la fin, et assez du milieu que nous pouvons travailler sur le motif répétitif. –

+0

Juste comme un indice. Encapsuler la commande et le DataReader dans Using-Blocks, qui prendra soin de jeter les objets. Aussi, juste comme une note, vous pouvez * déclarer * la commande en tant que variable privée dans votre classe, de sorte qu'elle n'a pas besoin d'être instanciée à chaque fois, et appeler ExexcuteScalar() pourrait être plus rapide/meilleur. – Bobby

+0

Sur une autre note, une exception StackOverFlow n'a rien à voir avec les objets non-jetés, cela signifie qu'une fonction a été appelée en boucle sans fin. Vérifiez que cette fonction n'est pas appelée à partir d'un événement pour qu'il se déclenche automatiquement. – Bobby

Répondre

1

Il est difficile d'être sûr sans la trace de pile, mais j'imagine que quelque part vous avez un appel récursif à une fonction qui augmente la taille de la pile d'appels à chaque itération. L'erreur StackOverflowException provient de la bibliothèque SQLite, mais je suppose que la plupart des appels sur la pile à ce stade sont vos propres fonctions. L'appel dans la bibliothèque SQLite était l'appel qui a cassé le dos de chameau, mais ce n'est pas nécessairement où l'erreur est. Publiez les (parties intéressantes de la) trace de pile et peut-être pouvons-nous vous dire plus précisément où se trouve votre erreur.