Monitor.Exit throws SynchronizationLockException
本文关键字:SynchronizationLockException throws Exit Monitor | 更新日期: 2023-09-27 18:27:33
所以,我已经收到这个错误一段时间了,我进行了一些测试,但我无法解决问题。在调用Monitor.Exit()时,我得到了System.Threading.SynchronizationException。首先,我为我使用的所有Monitor方法创建了一个包装,将"Locked"answers"Unlocked"打印到屏幕上。这打印出来很好,就在我呼叫Exit之前,它说锁被锁住了。当我调用exit时,它抛出错误并未能解锁我的对象。这在我的UI中是显而易见的。它说了一些关于不能从非同步块执行的内容?
注意:我的Monitor.Exit命令是在不同于我的Monitors.Enter命令的方法调用中调用的。它仍然是安全的,但这可能是问题所在吗?
编辑:背景信息:我正在实施一个类似马里奥的游戏。当马里奥进入过渡时,我的团队希望我们所有的计时器停止更新(阻止他们的线程),只对我们的玩家进行特定的更新。所有Timer线程都已经使用了一个名为TimerLock的公共锁。以下是此转换的示例代码。
public void Begin()
{
if (Monitor.TryEnter(ManagedTimer.Lock,100))
{
try
{
//Turn off updating for all objects
TurnOffPhysicsUpdate(); //Psuedocode for this...
//Create timer till end event
EndTimer = new System.Timers.Timer(600.00);
EndTimer.AutoReset = false;
EndTimer.Elapsed += EndTimer_Elapsed;
EndTimer.Enabled = true;
EndTimer.Start();
//Create swap timer
SwapTimer = new System.Timers.Timer(25.0);
SwapTimer.AutoReset = false;
SwapTimer.Elapsed += SwapTimer_Elapsed;
SwapTimer.Enabled = true;
SwapTimer.Start();
}
catch (Exception e)
{
EndFreeze();
Debug.WriteLine("Failed to setup transition: " + e.Message);
}
}
}
private void SwapTimer_Elapsed(object sender, ElapsedEventArgs e)
{
SwapTimer.Stop();
//Transition Mario State....
SwapTimer.Start();
}
private void EndTimer_Elapsed(object sender, ElapsedEventArgs e)
{
EndFreeze();
}
private void EndFreeze()
{
try
{
SwapTimer.Stop();
EndTimer.Stop();
TurnOnPhysicsUpdate(); //psuedocode
//Ensure Mario ends in the proper state
user.StateMachine.TransitionSizeState(newState);
}
catch (Exception e)
{
Debug.WriteLine("FATAL ERROR: " + e.Message);
}
finally
{
//Exception occurs here!!!!!!!!!!!!!
Monitor.Exit(ManagedTimer.Lock,"TimerLock");
}
}
当计时器调用EndTimer_Elapsed
方法时,您不在拥有锁的同一线程中,因此不允许在那里释放锁。
这是一个很好的例子,说明了为什么应该完全避免使用Monitor.Enter/Exit
。即使是并行编程专家也很难把一切都做好,这对其他人来说都是一个雷区。如果您坚持通过lock
语句使用Monitor,则会更难犯这种错误。:)
最后请注意,从您的示例中还不清楚您为什么使用此锁。您可以考虑发布一个不同的问题来解释您试图解决的同步问题,这样您就可以在没有Monitor.Enter/Exit
的情况下正确设计代码。