47 votes

Pourquoi "verrouiller (type de (MyType))" est-il un problème?

MSDN donne l'avertissement suivant à propos de la serrure de mot-clé en C#:

En général, éviter le blocage sur un public type, ou des cas au-delà de votre code de contrôle. La commune de constructions de verrouillage (ce), lock (typeof (MyType)), et de verrouillage ("myLock") de violer cette ligne directrice:

* lock (this) is a problem if the instance can be accessed publicly.
* lock (typeof (MyType)) is a problem if MyType is publicly accessible.

Pourtant, il ne donne aucun raisonnement solide pour cela. Le verrou(ce) est expliqué ici sur DONC. Je suis intéressé dans de verrouillage(typeof(MyType)) cas. Ce qui est dangereux à ce sujet?

Je vous remercie.

64voto

Michael Burr Points 181287

C'est dangereux parce que tout peut prendre de verrouillage de sorte qu'il est difficile, voire impossible, pour éviter une situation de blocage.

Il y avait un article sur ce ("Ne pas Verrouiller les Objets de Type!" un Dr GUI de l'article) avec quelques commentaires de Rico Mariani. Apparemment, l'article n'est plus disponible, mais il existe des "miroirs" flottant autour, y compris au http://bytes.com/topic/c-sharp/answers/249277-dont-lock-type-objects.

En voici un extrait:

Le problème fondamental ici est que vous ne possédez pas le type de l'objet, et vous ne savez pas qui d'autre pourrait y accéder. En général, c'est une très mauvaise idée de s'appuyer sur le verrouillage d'un objet que vous n'avez pas créer et ne sais pas qui d'autre peut accéder. Faire invite impasse. Le moyen le plus sûr est de ne verrouiller des objets privés.

Mais attendez, c'est encore pire que tout cela. Comme il s'avère, les objets sont parfois partagés entre les domaines d'application (mais pas à travers des processus) dans les versions actuelles de la .NET runtime. (Ce n'est généralement pas un problème puisque ils sont immuables.) Cela signifie qu'il est possible pour une AUTRE APPLICATION en cours d'exécution, même dans un domaine d'application différent (mais dans le même processus) de blocage de votre demande par l'obtention d'un verrou sur un type d'objet que vous souhaitez bloquer et de ne jamais le relâcher. Et il serait facile d'obtenir l'accès à ce type d'objet, parce que l'objet a un nom-le nom complet du type! Rappelez-vous que le verrouillage/SyncLock blocs (c'est un mot poli pour se bloque) jusqu'à ce qu'il peut obtenir un verrou. C'est évidemment très mauvais de s'appuyer sur un verrou qu'un autre programme ou un composant peut verrouiller et vous amener à une impasse.

28voto

Jon Skeet Points 692016

C'est le même problème qu'avec lock(this) - vous verrouillez une référence à laquelle un autre code a accès, donc il pourrait aussi se verrouiller dessus.

Si vous avez deux éléments de code non liés qui se verrouillent sur la même référence sans avoir l'intention de s'exclure l'un l'autre, dans le meilleur des cas, vous pourriez perdre un peu de performances en raison d'un manque de concurrence - et dans le pire des cas, vous pourriez introduire un blocage.

2voto

G-Wiz Points 4800

Parce que le résultat de typeof (MyType) (qui est un objet de type Type ) est largement accessible et que d'autres threads peuvent se verrouiller sur le même objet et maintenir ce verrou indéfiniment. Ensuite, la logique interne de MyType a effectivement cédé un contrôle significatif sur sa logique de synchronisation. Cela pourrait ne pas être un problème réel si cela est prévu, mais le codage défensif / sceptique devrait être votre modus operandi .

1voto

Letterman Points 1516

Je n'aime pas tout le concept de verrouillage de C #. Cela me semble être un bug d'architecture. Ils auraient dû créer une classe vide [comme ils l'ont fait avec EventArgs] (appelée Locker par exemple) qui est le seul objet verrouillable. De cette façon, tout le monde suivrait la meilleure pratique ...

Ou encore mieux, pour lui ajouter des propriétés telles que bool Locked {get; set;} (ou peut-être juste que je ne suis pas sûr)

0voto

Charles Bretana Points 59899

car la cible d'une serrure est UNIQUEMENT de créer un endroit pour stocker le verrou de type boolean (Suis-je bloqué ou pas) pour les autres threads à regarder....

L'erreur commune de croire que la cible d'une serrure est en fait en quelque sorte être verrouillé est tout simplement faux... Ce qui est "verrouillé" est, .... rien, moins que dans les méthodes qui peuvent accéder à certaines de mémoire partagée d'une manière dangereuse, d'écrire le code pour regarder le ce de verrouillage et de ne pas continuer jusqu'à ce qu'il a été publié... en utilisant un Type d'objet, comme un verrouillage de cible est incorrecte, car les fragments de code n'importe où dans l'ensemble de la solution de processus de l'espace peut accéder à ce type d'objet et de modifier la synchro bloc de la serrure booléenne est stocké dans. La création d'un localement étendue de l'objet permet de mieux ensurethat seulement ces threads et des méthodes d'accès ou le désordre de votre "à risque" de la mémoire partagée peut également accéder et/ou modifier la serrure.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X