2010-02-18 13 views
8

J'ai des objets, ils ont des verrous. Je veux tester s'ils sont verrouillés sans acquérir de verrou. L'idée est si je TryEnter() ils je dois Exit() si vrai pour vérifier seulement le verrou correctement.Testez un verrou sans l'avoir acquis?

Cela semble être une question vraiment fondamentale, comment cela se fait-il?

Répondre

22

Quelles informations possibles pouvez-vous obtenir en sachant que le verrou a été déverrouillé lorsque vous l'avez regardé? Au moment où vous prenez une décision basée sur cette information, le verrou peut être déjà pris.

+3

+1, exactement. Répondre à cette question sur l'état passé de la serrure ne peut que vous conduire à prendre des décisions incorrectes. – JaredPar

+0

Je verrouille les choses pour que je puisse voir si elles sont utilisées. par exemple. Deux threads ne détruisent donc pas les mêmes ressources partagées. Je veux voir si ce travail est fait. Je pourrais faire la même chose avec une valeur IsBeingUsed mais l'objet pour le verrou existe déjà et les verrous agissent de la même manière, à l'exception de pouvoir vérifier s'ils sont verrouillés sans out en mettant la valeur à locked. – QueueHammer

+3

Lorsque vous examinez IsBeingUsed, le thread peut déjà avoir arrêté le travail utile, mais un changement de contexte peut avoir eu lieu avant la mise à jour de IsBeingUsed. –

2

Parce que la déclaration de verrouillage est équivalent à:

System.Threading.Monitor.Enter(x); 
try { 
    ... 
} 
finally { 
    System.Threading.Monitor.Exit(x); 
} 

Pouvez-vous faire tout cela?

bool ObjectWasUnlocked(object x) 
{ 
    if(System.Threading.Monitor.TryEnter(x)) 
    { 
     System.Threading.Monitor.Exit(x); 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

Notez que je nommant cette fonction « objet était- débloqué » par opposition à « ObjectIsUnlocked ». Il n'y a aucune garantie qu'il sera toujours déverrouillé lorsque la fonction est retournée.

+0

Dans cette solution, vous obtenez le verrou, ce que l'OP ne voulait pas faire. – JaredPar

+0

@JaredPar: Oui, bon point. –

3

Je me demandais la même chose tout en essayant de vérifier mon code pour le verrouillage correct. Je suis venu avec une méthode en utilisant un deuxième thread. Si le verrou est disponible pour le thread appelant, mais indisponible pour un deuxième thread, il doit être conservé par le premier. Je ne l'utiliserais pas dans le code de production - il y a une condition de concurrence qui pourrait exploser. Cependant, mes tests unitaires sont pour la plupart à simple thread, donc c'était utile.

+0

Ce code est cassé. Le premier 'Monitor.Exit (lockObject)' (dans le bloc 'finally') est appelé même si le verrou n'a pas pu être acquis. –

+0

@Sebastian Krysmanski: bon point, pas besoin de finalement. fixe et nettoie – GranBurguesa