Anycpu 用に 4.0 コンパイラによって生成された IL を見て、それを C# に逆にすると、私が得ることができる最も近いロックと同等の実装は次のようになります。
object x = new object();
bool lockTaken = false;
// lock
try{
System.Threading.Monitor.Enter(x, ref lockTaken)
DoSomeThing();
}
finally
{
if (lockTaken)
{
System.Threading.Monitor.Exit(x);
}
}
ロックが取得され、スレッドが中止され、ロックが解放されず、競合/デッドロックが発生する状況を防ぐためにすべてが行われます。この警告は、基本的に、適切な、そして何よりも失敗した状況で、Enter 呼び出しと Exit 呼び出しのバランスをとるように指示します。lock ステートメントは、その目標を達成するための最も単純な抽象化です。
このILに基づいて:
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
.try
{
IL_0003: ldsfld object p::x
IL_0008: dup
IL_0009: stloc.1
IL_000a: ldloca.s 0
IL_000c: call void [mscorlib]System.Threading.Monitor::Enter(object, bool&)
IL_0011: nop
IL_0012: nop
IL_0013: call void p::DoSomething()
IL_0018: nop
IL_0019: nop
IL_001a: leave.s IL_002c
} // end .try
finally
{
IL_001c: ldloc.0
IL_001d: ldc.i4.0
IL_001e: ceq
IL_0020: stloc.2
IL_0021: ldloc.2
IL_0022: brtrue.s IL_002b
IL_0024: ldloc.1
IL_0025: call void [mscorlib]System.Threading.Monitor::Exit(object)
IL_002a: nop
IL_002b: endfinally
} // end handler
IL_002c: nop
IL_002d: ldsfld object p::x
IL_0032: call void [mscorlib]System.Threading.Monitor::Enter(object)
IL_0037: nop
.try
{
IL_0038: nop
IL_0039: call void p::DoSomething()
IL_003e: nop
IL_003f: nop
IL_0040: leave.s IL_0050
} // end .try
finally
{
IL_0042: nop
IL_0043: ldsfld object p::x
IL_0048: call void [mscorlib]System.Threading.Monitor::Exit(object)
IL_004d: nop
IL_004e: nop
IL_004f: endfinally
} // end handler
IL_0050: nop
IL_0051: ret