public static void EmitLock(this ILProcessor il, Action loadSyncRoot, Action block) { var lockTaken = new VariableDefinition(/*"$lockTaken",*/ il.Body.Method.Module.ImportReference(typeof(bool))); il.Body.Variables.Add(lockTaken); var syncRoot = new VariableDefinition(/*"$root",*/ il.Body.Method.Module.ImportReference(typeof(object))); il.Body.Variables.Add(syncRoot); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Stloc, lockTaken); il.EmitTryFinally(() => { loadSyncRoot(); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stloc, syncRoot); il.Emit(OpCodes.Ldloca, lockTaken); il.Emit(OpCodes.Call, il.Body.Method.Module.ImportReference(_monitorEnter)); block(); }, () => { il.Emit(OpCodes.Ldloc, lockTaken); using (il.BranchIfFalse()) { il.Emit(OpCodes.Ldloc, syncRoot); il.Emit(OpCodes.Call, il.Body.Method.Module.ImportReference(_monitorExit)); } }); }