2009-02-17 8 views
1

qui du code suivant est la situation plus appropriée lorsque plusieurs threads accéder à la fonctionC#: Enfilez fonction de sécurité

public ArrayList CallMe1() 
    { 
     ArrayList al = new ArrayList(); 

     lock(al.SyncRoot) 
     { 
      al.Add("33"); 
      al.Add("45"); 

      return al; 
     } 

    } 

    public ArrayList CallMe2() 
    { 

     ArrayList al = new ArrayList(); 

     Monitor.Enter(al); 

     al.Add("33"); 
     al.Add("45"); 
     Monitor.Exit(al); 

     return al; 


    } 

Répondre

-2

le problème avec .net verrouillage est que dans le cas d'une impasse, il ne va pas jeter une exception ou quoi que ce soit. Par ailleurs, vous verrouillez à chaque fois un ArrayList nouvellement créé. Comment est-ce censé aider? Je préfère créer un objet statique quelque part et prendre un verrou dessus.

+0

serait reconnaissant si le vote à la baisse est expliqué. – Sesh

+0

objet de verrouillage statique quelque part? ça ne me semble pas une bonne idée ... – Svish

+0

Sauf si c'est une méthode statique. .) – Rytmis

9

Il n'y a pas d'état partagé dans ce cas, donc la synchronisation est inutile.

Cependant, en supposant que le arraylist a été état partagé, ce qui suit s'applique:

Ils sont tous les deux les mêmes (lock implements Monitor internally).

Principalement.

Votre deuxième version doit libérer le moniteur dans un bloc finally, sinon, si le code déclenche une exception, le verrou ne sera jamais libéré et entraînera des interblocages dans votre application. En résumé, utilisez la première version (lock (...) {... }) pour éviter une saisie inutile et d'éventuelles erreurs.

+0

ok ... en fait l'arraylist devrait être partagé ...C'était question en 70-536 examen que je viens de répondre et effacé avec un score décent de 950 .. j'avais des doutes quant à celui-ci ... –

+0

compte tenu de l'arralylist est partagée ... qui est un meilleur code? J'ai été intrigué avec le retour avec le verrou {return al;} J'ai choisi Monitor.enter et quitter ... je me souviens de vérifier sur msdn le premier verrou est utilisé .. –

+0

Parce que le verrou implémente un bloc finally, l'instruction return sera toujours exécutée le contenu du bloc finally, donc il va libérer le moniteur. –

8

Aucune. Les fonctions ne partagent aucune donnée, donc aucune syncronisation n'est nécessaire.

6

Ni l'un ni l'autre. Aucune de vos fonctions n'a d'état partagé (seules les variables locales), ce qui les rend intrinsèquement réentrantes. Aucune synchronisation n'est requise.

1

Comme d'autres réponses ont déclaré verrouiller utilise moniteur mais il le fait d'une meilleure manière que votre deuxième exemple. C'est mieux car il encapsule les appels à surveiller dans un bloc try finally en s'assurant que le verrou est libéré s'il y a une exception.

Pour cette raison, je vous recommande d'utiliser la serrure pour presque toutes les opérations.

+0

que se passe-t-il s'il y a une exception à l'intérieur du verrou? –

+0

Étant donné qu'aucune exception ne se produira (comme c'était une question d'examen), j'ai choisi monitor.enter et j'ai quitté ... avais-je raison? –

+0

J'ai supposé que le code que vous avez posté était juste un exemple simple et que vous n'alleriez pas simplement ajouter "33" et "45". Donc j'ai supposé qu'il y aurait au moins la possibilité d'une ArgumentNullException. – ng5000

1

1 - Vous n'avez pas besoin de verrou ici.

2 - N'utilisez pas le moniteur si vous pouvez le faire avec un verrou.

3 - Dans le premier exemple, vous verrouillez un objet SyncRoot, c'est mieux que de le verrouiller sur un tableau.

0

Vous pouvez également trouver une partie de la réponse here.

Renvoyer l'instruction à l'intérieur (CallMe1) ou à l'extérieur (CallMe2) le verrou ne fait également aucune différence.