2009-10-18 10 views
0

J'ai eu un petit problème. Parfois, lorsque j'essaie d'appeler le code suivant, les méthodes remove lèvent une exception avec le message "la clé n'est pas présente dans le dictionnaire".C# exception: La clé n'est pas présente dans le dictionnaire

private Dictionary<IPAddress, ARPHostEntry> dIPHostTable; 
private Dictionary<MACAddress, ARPHostEntry> dMACHostTable; 

public HostTable() 
{ 
    dIPHostTable = new Dictionary<IPAddress, ARPHostEntry>(); 
    dMACHostTable = new Dictionary<MACAddress, ARPHostEntry>(); 
} 

public void AddHost(ARPHostEntry arphEntry) 
{ 
    lock (dMACHostTable) 
    { 
     if (dMACHostTable.ContainsKey(arphEntry.MAC)) 
     { 
      dMACHostTable.Remove(arphEntry.MAC); 
     } 
     dMACHostTable.Add(arphEntry.MAC, arphEntry); 
    } 
    lock (dIPHostTable) 
    { 
     if (dIPHostTable.ContainsKey(arphEntry.IP)) 
     { 
      dIPHostTable.Remove(arphEntry.IP); 
     } 
     dIPHostTable.Add(arphEntry.IP, arphEntry); 
    } 
} 

La classe ARPHostEntry est un simple calss qui détient une-adresse IP et un associé MAC-Adresse où les deux fiels dans cette classe sont en lecture seule. Le programme est multithread, mais je verrouille les dictionnaires de cette classe chaque fois que je les utilise.

Je suis sans défense. Pourquoi cette exception existe-t-elle?

meilleures salutations

Modifier

Pour plus de précisions, la réponse acceptée est correcte. L'exception générée était un problème causé par l'accès inter-thread à mes dictionnaires.

Répondre

2

La méthode Remove ne doit pas déclencher une telle exception, elle doit renvoyer false si la clé n'est pas trouvée (Voir here). Au lieu de supprimer et d'ajouter, pourquoi n'essayez-vous pas de mettre à jour la valeur de la clé?

+0

O_O. D'accord, je vais vérifier à nouveau ceci. Étrange. Et je vais essayer de mettre à jour seulement la valeur. Merci. – Emiswelt

+0

@Emiswelt: Dites-nous si cela fonctionne (ou pas). –

+0

Je suis probablement un peu en retard mais je l'ai réparé comme vous l'avez suggéré. Avec un modèle multihtreading plus propre (ISyncrhonizeInvoke) dans la classe appelante, cela fonctionne maintenant. – Emiswelt

0

Votre exemple ne précise pas si vous partagez vraiment les tables hôtes entre threads. Les tables d'hôtes privées ne devraient-elles pas être statiques?

+0

Non, j'ai besoin de plusieurs instances de cette classe pour plusieurs interfaces réseau qui sont partagées avec beaucoup d'autres objecty implémentant des couches supérieures et de nombreux threads. – Emiswelt