2013-10-30 17 views
6

Abbiamo avuto una discussione sul lavoro riguardante il blocco e cosa accade esattamente. Il codice che ha attivato questa discussione è:Quali sono le implicazioni dell'uso del blocco (typeof (stringa))

 string name = (string)context.Cache[key]; 

     if (String.IsNullOrEmpty(name)){ 

      lock (typeof(string)){ 
       name = (string)context.Cache[key]; 
       //.. other code to get the name and then store in the cache 
      } 
     } 

Io vedo questo come straight-forward: cerca un valore nella cache, se non è lì poi ottenere un blocco in modo da niente altro interrompe mentre il codice prende il nome e lo memorizza nella cache.

La nostra discussione si è concentrata sul fatto che (typeof (stringa)) sia il modo migliore di fare le cose e che cosa è esattamente ciò che fa.

La mia domanda è cosa fa esattamente lock (typeof (stringa))? Crea una stringa locale da utilizzare come lock o crea qualcosa con un ambito più ampio e quindi potenzialmente non sicuro.

MSDN lock statement

+2

No, blocca tutto il tipo - [e può essere pericoloso] (http://stackoverflow.com/questions/1603008/why-is-lock-typeof-mytype-a-problem).Se creasse solo una stringa casuale da bloccare, in che modo gli altri blocchi saprebbero bloccare la stessa istanza di quella stringa? Ti consiglierei di creare un oggetto fittizio da bloccare come 'oggetto privato _lockOnThis = new object()'. – vcsjones

+0

Penso che typeof (SomeType) restituirà sempre la stessa istanza di tipo per lo stesso tipo. Quindi dovresti usare un'istanza disponibile globalmente come un blocco che non è la migliore idea di IMHO. – helb

+0

@vcsjones Attualmente sto rimuovendo tutte le istanze di questo modo di bloccare, ma ero interessato a ciò che faceva esattamente. –

risposta

2

Se si blocca su un Type vorrà dire che avete un'esclusione accesso reciproco sulla base di tale istanza del Type. Le implicazioni sono che due thread nell'applicazione che eseguono ciò si bloccano inavvertitamente l'un l'altro o causano deadlock imprevisti.

Ricorda, typeof(someType) restituisce solo un'istanza Type.

In genere è consigliabile dedicare un oggetto al blocco di un processo complesso, ad esempio la dichiarazione di un readonly object nella classe. Se il lucchetto ha solo bisogno di aggirare qualche accesso a una variabile privata, diciamo una collezione, quindi bloccare quella raccolta è abbastanza buona.

+0

Questa è stata la conclusione che alla fine abbiamo raggiunto nella nostra discussione. –

+0

Non ero sicuro se accettare la risposta di Jon Skeet o quella di Michael poiché entrambe sono buone risposte. Mike ha meno punti in modo da farlo oscillare. –

1

Come mostrato nella pagina si collega a:

In generale, evitare di bloccare su un tipo di pubblico, o di casi che esulano dal controllo del codice. Il comune costrutto lock (this), lock (typeof (MyType)) e lock ("myLock") violano questa linea guida:

lock (typeof (MyType)) è un problema se MyType è pubblicamente accessibile.

8

La mia domanda è cosa fa esattamente lock (typeof (stringa))?

Si blocca sull'oggetto Type cui dal riferimento che i rendimenti typeof operatore.

Ciò significa alcun codice che fa la stessa cosa ovunque all'interno dello stesso processo (o almeno lo stesso dominio di applicazione) condivideranno lo stesso blocco. Mi sembra una cattiva idea.

vorrei suggerire si crea un oggetto solo per il bloccaggio su:

private static readonly object CacheLock = new object(); 

... 

lock (CacheLock) 
{ 
    ... 
} 

In questo modo si può facilmente vedere cosa sta succedendo per bloccare su tale oggetto.

+0

Quale sarebbe il vantaggio del blocco su un oggetto dedicato bloccando eccessivamente la risorsa condivisa principale? Dì se questa cache è solo un oggetto che è dichiarato allo stesso modo del tuo 'CacheLock'. –

+0

@ MichaelJ.Gray: significa che puoi facilmente controllare cosa blocca su quell'oggetto. Sai se qualche codice all'interno di .NET si blocca sulla cache? Io non. –

+0

Immagino di essere un po 'confuso con il tuo commento. In che modo è più semplice verificare se qualcosa sta bloccando su 'CacheLock' piuttosto che sulla cache a cui si sta accedendo (non di tipo (Cache))? Se ho un 'lock (this.cache) {..}' dovrebbe essere più corretto, credo. Sono incerto sul motivo per cui la tendenza è iniziata con qualcosa come 'lock (this.cacheLocker) {..}' contro singoli oggetti; Riesco a capire il 'cacheLocker' per i processi complessi in cui i tipi sono internamente sicuri per i thread ed espongono metodi sicuri per i thread pubblici. –

Problemi correlati