2010-02-23 11 views
2

Je ne parviens pas à aller au fond de cette erreur car cela se produit uniquement dans une instance et je ne trouve aucun code pouvant être à l'origine de l'erreur.La collection a été modifiée; opération d'énumération peut ne pas s'exécuter

J'ai un service Web 3.5 que j'appelle depuis un client CAB multithread. J'ai un tas de tests unitaires contre le service web (du code 3.5 et 2.0), et ça marche très bien. Cependant, dans l'application actuelle, cela ne fonctionne pas 90% du temps et, les 10% restants du temps, il décide de travailler.

Le code:

Friend Function ExecuteSearch(ByVal query As String) As List(Of SomeObject) 
    Dim searchResults As List(of Object) = _searcher.UserSearch(query) 
    Return searchResults 
End Function 

// In Searcher 
Public Function UserSearch(ByVal query As String) As List(Of SomeObject) 
    Return Translate(Search.GetResults(query)) 
End Function 

// In Search 
Public Function GetResults(ByVal query As String) As List(Of SomeObject) 
    Dim service As New FinderService.FinderService() 
    Dim results As New List(Of String) 
    Dim serviceResults As IEnumerable(Of String) = service.Search(query) // <-- ERRORS OUT HERE 

    results.AddRange(serviceResults) 

    Return results 
End Function 

// In the service 
Public Function Search(ByVal query As String) As IEnumerable(Of String) 
     Initialize() // Initializes the _accounts variable 
     Dim results As New List(of String) 
     For Each account As User In _accounts 
      If a bunch of conditions Then 
       results.Add(account.Name) 
      End IF 
     End For 

     Return results 
End Function 

Les points d'arrêt ont frappé ces codes (dans cet ordre). La ligne qui fait l'erreur est dans la méthode "GetResults".

Toute aide serait appréciée.

+0

Je voulais juste ajouter que le service a été configuré en mode singleton. – Sadhana

+0

On ne sait toujours pas d'où provient l'erreur. Quel appel de ligne ou de bibliothèque renvoie l'exception que vous obtenez? –

+0

Je comprends les hits d'exception sur la ligne dans le client, mais en fait c'est une propagation d'une exception dans le service. – user76035

Répondre

7

Ah, les bug logiciel inhabituel: D

_accounts Apparemment, sont modifiés au cours de la boucle. Vous pouvez l'alléger en faisant

For Each account As User In _accounts.ToList() 

donc une copie de _accounts en cours est créé et énumérait et non la collecte effective qui pourrait changer

+0

_accounts est trop volumineux pour être copié. Depuis que j'ai posté cette question, j'ai ajouté un verrou sur l'emplacement * seulement * où _accounts est mis à jour, mais cela n'a pas fait de différence. sous publique Initialize SyncLock _accounts _accounts.AddRange (obtenir des comptes de db) Fin SyncLock end sub – Sadhana

+0

Vous vous rendrez compte que copier les références, pas tout le contenu Donc, à moins que vous avez dit un demi-milliard de comptes, il ne sera pas un problème? Néanmoins, si vous voulez ajouter un verrou, vous devez également utiliser la boucle SyncLock ForEach. – user76035

+0

@wwosik - pas un demi-milliard; juste un couple de millions. :-) Je vais aller avec le ToList. – Sadhana

Questions connexes