2012-06-27 1 views
10

を投げる)スピンロックは、私がスピンロックを使用しようとしていますが、ときに私は(callSpinLock.Exitシングルスレッドコンソールアプリでも、この最も基本的なコードは次の例外をスローSynchronizationLockException

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

は、全体のソースコードです。 ..

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

メッセージには、Exitを呼び出すスレッドと同じスレッドがロックを所有していないと表示されていますが、コードからは明らかです。 –

答えて

14

SpinLockは構造体で、読み取り専用フィールドから読み取ります。 C#の仕様では、この場合、潜在的に変化する関数を呼び出すためには、構造体を変更可能なローカル変数にコピーする必要があると言います。これはカバーの下で起こります。

あなたのロックの新しいコピーでEnterとExitへの呼び出しが行われます。そのため、Enterはロックされていないロックで動作しています。

SpinLock変数が変更されているため、読み込み専用にしないでください。

+0

ああ、値の型で "readonly"を使うことは、フィールドが代入可能ではないだけでなく、値が不変であることを意味し、それを確実に読み取るために値をコピーすることを意味します。 ありがとう –

関連する問題