2011-10-12 11 views
7

Ho una situazione in cui ReadWriterLockSlim lancia l'eccezione "System.Threading.SynchronizationLockException - Il blocco scrittura viene rilasciato senza essere trattenuto." quando provo ad eseguire ExitWriteLock(). Per quanto posso dire, questo non dovrebbe accadere perché i thread successivi che entrano nel blocco try "bloccheranno" finché non potranno ottenere il lock. Mi sto perdendo qualcosa qui?Blocco scrittura sbloccato senza blocco

Il problema è molto simile a this one, tuttavia nessuna soluzione è stata pubblicata lì.

//Code simplified for example. 

public class i18nService { 
    internal static ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); 

    private string ProcessText() 
    { 
     try { 
      cacheLock.EnterWriteLock(); 
      return "xyz"; 
     } 
     finally { 
      cacheLock.ExitWriteLock(); // Error is throwing here. 
     } 
    } 
} 

Grazie mille per il vostro aiuto :-)

risposta

4
try { 
     cacheLock.EnterWriteLock(); 
     return "xyz"; 
    } 
    finally { 
     cacheLock.ExitWriteLock(); // Error is throwing here. 
    } 

Q: Cosa succede se cacheLock.EnterWriteLock(); fallisce?

A: l'istruzione finally viene eseguita.

  • cacheLock.ExitWriteLock(); viene chiamato
  • Ma noi non hanno il blocco

Prova questa:

private string ProcessText() 
{ 
    cacheLock.EnterWriteLock(); 
    try { 
     return "xyz"; 
    } 
    finally { 
     cacheLock.ExitWriteLock(); // Error is throwing here. 
    } 
} 

Presumibilmente .NET è stato progettato in modo tale che, se EnterWriteLock() fallisce, il lucchetto viene rilasciato (o mai tenuto affatto).

+0

G'day Brendan. Grazie per la risposta. In realtà ho pensato lungo una linea simile ma non sono sicuro che sia il caso. da http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.enterwritelock.aspx "Questo metodo blocca fino a quando il thread chiamante non entra nel blocco e pertanto potrebbe non tornare mai. Utilizzare il metodo TryEnterWriteLock bloccare per un intervallo specificato e quindi tornare se il thread chiamante non ha inserito la modalità di scrittura durante tale intervallo. " Tuttavia, come fai notare, non sto permettendo un'eccezione su EnterWriteLock() ... hmmm ... lasciami giocare ancora un po '. –

6

Ma se viene generato un errore nel tentativo di inserire il blocco, verrà eseguito definitivamente, senza tenerlo premuto. Perché non semplicemente vendersi a:

... 
finally { 
    if(cacheLock.IsWriteLockHeld) 
     cacheLock.ExitWriteLock(); 
} 
... 
+0

Ciao Petar. Penso che tu (e Brendan) abbia ragione. Saluti :-) –