48 votes

Existe-t-il un moyen de détecter si un objet est verrouillé?

Existe-t-il un moyen de déterminer si un objet est verrouillé en C #? J'ai la position peu enviable, dans la conception, où je lis depuis une file d'attente à l'intérieur d'une classe, et je dois vider le contenu dans une collection de la classe. Mais cette collection est également en lecture / écriture à partir d'une interface en dehors de la classe. Donc, évidemment, il peut y avoir un cas où la collection est en cours d'écriture, comme je veux y écrire en même temps.

Je pourrais programmer autour, en utilisant un délégué, mais ce serait moche.

45voto

casperOne Points 49736

Vous pouvez toujours faire appel à la statique TryEnter méthode sur l' Monitor de la classe à l'aide d'une valeur de 0 pour la valeur d'attendre. Si elle est verrouillée, l'appel retourne la valeur false.

Cependant, le problème est ici que vous devez vous assurer que la liste que vous essayez de synchroniser l'accès est verrouillé sur lui-même afin de synchroniser l'accès.

C'est généralement une mauvaise pratique d'utilisation de l'objet que l'accès est en cours de synchronisation que l'objet de verrouillage (exposer trop de détails internes d'un objet).

Rappelez-vous, la serrure peut être sur de rien d'autre, donc, juste l'appel de cette sur cette liste est inutile, sauf si vous êtes sûr que la liste est ce qui est verrouillé.

11voto

Barry Kelly Points 30330

Monitor.TryEnter réussira si l'objet n'est pas verrouillé et retournera false si, à ce moment précis, l'objet est verrouillé. Cependant, notez qu'il y a une course implicite ici: l'instance que cette méthode retourne, l'objet ne peut plus être verrouillé.

7voto

Je ne sais pas si un appel statique à TryEnter avec un temps égal à 0 garantira que le verrou ne sera pas acquis s'il est disponible. La solution que j'ai testée pour vérifier en mode débogage que la variable de synchronisation était verrouillée était la suivante:

 #if DEBUG
// Make sure we're inside a lock of the SyncRoot by trying to lock it.
// If we're able to lock it, that means that it wasn't locked in the first
// place.  Afterwards, we release the lock if we had obtained it.
bool acquired = false;
try
{
    acquired = Monitor.TryEnter(SyncRoot);
}
finally
{
    if (acquired)
    {
        Monitor.Exit(SyncRoot);
    }
}
Debug.Assert(acquired == false, "The SyncRoot is not locked.");
#endif
 

6voto

Alex Kliuchnikau Points 8411

Actuellement, vous pouvez appeler le Moniteur.TryEnter pour objectif de vérifier si l'objet est verrouillé ou non.

Dans .NET CLR 4.0 équipe va ajouter "Verrouillage de l'inspection de l'API"

Voici une citation de Rick Byers article:

verrouillage de l'inspection
Nous sommes à l'ajout de certaines Api simple pour ICorDebug qui vous permettent de découvrir géré serrures (Moniteurs). Par exemple, si un thread est bloqué dans l'attente d'un verrou, vous pouvez trouver ce que d'autres thread est actuellement en maintenant le verrou (et si il y a un temps d'attente).

Ainsi, avec cette API, vous serez en mesure de vérifier:
1) Quel objet est le maintien d'un verrou?
2) Qui est en attente pour elle?

Espérons que cette aide.

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