Supposons que j'ai une classe de collection personnalisée qui fournit une synchronisation de thread interne. Par exemple, une méthode simplifiée Ajouter pourrait ressembler à ceci:Contrats de collection et threads
public void Add(T item)
{
_lock.EnterWriteLock();
try
{
_items.Add(item);
}
finally
{
_lock.ExitWriteLock();
}
}
Le dernier code des marchés se plaint que CodeContracts: ensures unproven: this.Count >= Contract.OldValue(this.Count)
. Le problème est que cela ne peut vraiment pas être prouvé. Je peux m'assurer que, en interne, dans la serrure, le nombre sera plus grand que sa valeur précédente. Je ne peux pas assurer cela, cependant, à la sortie de la méthode. Après la fermeture du verrou et avant la fin de la méthode, un autre thread peut émettre deux suppressions (probablement des éléments différents), invalidant le contrat. Le problème fondamental ici est que les contrats de collecte ne peuvent être considérés comme valables que dans un contexte de verrouillage particulier et seulement si le verrouillage est utilisé de manière cohérente dans toute l'application pour tout accès à la collection. Ma collection doit être utilisée à partir de plusieurs threads (avec Add-Remove non conflictuel étant un cas d'utilisation valide), mais j'aimerais quand même implémenter ICollection<T>
. Dois-je simplement prétendre que je peux répondre à cette exigence avec un supposé, même si je sais que je ne peux pas? Il me semble qu'aucune des collections de la BCL ne peut assurer cela non plus.
EDIT:
D'après une enquête plus approfondie, il semble que le plus gros problème est que le contrat rewriter peut introduire des affirmations incorrectes, conduisant à la durée d'exécution des échecs. Sur cette base, je pense que ma seule option est de restreindre mon implémentation d'interface à IEnumerable<T>
, car le contrat sur ICollection<T>
implique que la classe d'implémentation ne peut pas fournir de synchronisation de thread interne (l'accès doit toujours être synchronisé de manière externe). Ceci est acceptable pour mon cas particulier (tous les clients qui souhaitent muter la collection connaissent directement le type de classe), mais je suis certainement intéressé d'entendre s'il y a d'autres solutions à cela.
Si vous utilisez supposer que vous pouvez toujours obtenir des erreurs de contrat d'exécution. –