有时在使用Monitor进行并发同步编程时,会产生SynchronizationLockException异常,抛出的异常内容是"Object synchronization method was called from an unsynchronized block of code." 。意思是“对象同步方法是从非同步代码块调用的。”
出现这个异常的原因是在相同的代码块中,Monitor的锁对象不一致。
我们知道,Monitor一般都会使用引用对象当做锁对象。但是当Monitor的锁对象不一致时,就会抛出SynchronizationLockException异常。
如下代码就会抛出SynchronizationLockException异常:
protected object _locker=new object(); protected object _lockerTmp=new object(); try{ Monitor.Enter(_locker); //to do something } finally{ Monitor.Exit(_lockerTmp); } //在同一代码块中,如果Monitor的锁对象不一致,则会抛出SynchronizationLockException异常。 //内容为"Object synchronization method was called from an unsynchronized block of code."
修改一下上面的代码,将Monitor的锁对象改为一致,就正常了。请看如下代码:
//正常的情况 protected static readonly object _locker=new object(); try{ Monitor.Enter(_locker); //to do something } finally{ Monitor.Exit(_locker); }
提醒,千万不要使用表达式体(=>)给锁对象赋值,每次调用表达式体获取的对象都不相同!
关于表达式体(=>)和等号(=)获取值的区别请看我的另一篇随笔《.net 表达式返回值和等号赋值的区别》