2010-07-30 6 views
3

Nous utilisons des extensions parallèles dans une partie de notre application vb.net pour récupérer un datatable d'un dictonary (de ficelle, datatable). Dans la méthode pour récupérer la table, nous utilisons Monitor.TryEnter. Parfois, nous obtenons l'erreur "La méthode de synchronisation d'objet a été appelée à partir d'un bloc de code non synchronisé." Voici ce que notre méthode ressemble à:Monitor.TryEnter Conseils

 Try 
      if Monitor.TryEnter(_ProductCollection, 200) = true then 
       _ProductCollection.TryGetValue(name, ReturnValue) 
      end if 
     Finally 
      Monitor.Exit(_ProductCollection) 
     End Try 

Dois-je essayer de mettre en place une boucle pour nous assurer que nous obtenons le verrou, avant d'essayer de le quitter? Je pense que l'erreur est levée parce que j'essaye de faire le monitor.exit même si le monitor.tryenter est faux.

+0

dictionnaires support de lecture de plusieurs threads à la fois, alors peut-être vous ne même pas besoin d'appels de moniteur (si vous écrivez potentiellement en même temps, alors vous avez besoin, et vous devez protéger l'écriture avec les mêmes appels de synchronisation). – zneak

+0

Oui, nous lisons et écrivons en même temps. le code ci-dessus est très similaire à la fonction d'écriture. –

Répondre

3

L'erreur est éjecté de l'appel Monitor.Exit. Ce qui se passe est que TryEnter timesout de temps en temps et la serrure n'est pas acquis, mais Monitor.Exit est toujours appelé car il est le bloc finally. C'est le problème. Voici comment vous pouvez le réparer.

Dim acquired As Boolean = False 
Try 
    acquired = Monitor.TryEnter(_ProductionCollection, 200) 
    If acquired Then 
    ' Do your stuff here. 
    End If 
Finally 
    If acquired Then 
    Monitor.Exit(_ProductionCollection) 
    End If 
End Try 
+0

Vous pouvez vous épargner la section 'boolean' si vous faites le' Try'/'Finally' l'intérieur d'un' Si Monitor.TryEnter (...) 'comme la [documentation MSDN] (http://msdn.microsoft.com /en-ca/library/4tssbxcw.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2) pour 'Monitor.TryEnter' montre. –

+0

@JeffBridgman: True. Cependant, j'ai choisi spécifiquement la structure ici, car il peut être facilement durci contre des exceptions asynchrones par régions d'exécution limitées par un simple appel à 'RuntimeHelpers.PrepareConstrainedRegions' avant le mot-clé' Try'. Certes, ce serait une chose assez ésotérique à faire. –