2012-06-27 11 views
10

Sto cercando di usare SpinLock, ma anche questo codice più fondamentale in un unico thread console app genera la seguente eccezione quando ho callSpinLock.Exit()SpinLock gettando SynchronizationLockException

System.Threading.SynchronizationLockException was unhandled by user code 
    Message=The calling thread does not hold the lock. Source=mscorlib 

Ecco l'intero codice sorgente. ..

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 

namespace ConsoleApplication48 
{ 
    class Program 
    { 
     static readonly SpinLock SpinLock = new SpinLock(); 
     static void Main(string[] args) 
     { 
      bool lockTaken = false; 
      try 
      { 
       SpinLock.Enter(ref lockTaken); 
       if (lockTaken) 
        Console.WriteLine("Lock taken"); 
      } 
      finally 
      { 
       if (lockTaken) 
        SpinLock.Exit(); 
      } 
      Console.WriteLine("Done"); 
     } 
    } 
} 
+0

Il messaggio indica che il blocco non è di proprietà dello stesso thread che chiama Exit, ma dal codice è chiaramente. –

risposta

14

SpinLock è una struttura, e si sta leggendo da un campo di sola lettura. La specifica C# dice che in questo caso, per chiamare una funzione potenzialmente mutante, la struttura deve essere copiata su una variabile locale mutabile. Questo succede sotto le coperte.

Le chiamate per entrare ed uscire si verificano su una nuova copia del lucchetto. Per questo motivo, Enter funziona su un lucchetto sbloccato.

Non rendere la variabile SpinLock in sola lettura perché sta subendo una mutazione.

+0

Ah, quindi usare "readonly" con un tipo di valore non solo specifica che il campo non è assegnabile ma implica anche che il valore è immutabile e per garantire che copi il valore quando lo leggi. Grazie –

Problemi correlati