【发布时间】:2014-12-18 12:55:15
【问题描述】:
所以,我已经收到这个错误一段时间了,我进行了一些测试,但我无法找出问题所在。调用 Monitor.Exit() 时出现 System.Threading.SynchronizationException。首先,我为我使用的所有 Monitor 方法创建了一个包装器,将“Locked”和“Unlocked”打印到屏幕上。这在我调用 Exit 之前打印得很好,它说锁已锁定。当我调用 exit 时,它会引发错误并且无法解锁我的对象。这在我的 UI 中是显而易见的。它说不能从非同步块执行?
注意:我的 Monitor.Exit 命令是在不同的方法调用中调用的,然后是我的 Monitor.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");
}
}
【问题讨论】:
-
听起来你的进入和退出调用不同步,如果你能原谅双关语的话。
-
退出时你在正确的线程上吗?它必须从进入的同一线程中退出
-
当您说不同步时,您是什么意思?我知道该对象在我调用时被锁定。我所能想到的是,它们不是从同一个方法调用的事实......
-
这个问题很模糊。显示一些示例代码可能会有所帮助。脑海中浮现的一个明显问题是,“你真正想要解决代码中的什么条件?” -- 附加信息,例如,这是一个 Windows 窗体应用程序吗?将有助于我们更好地理解问题。
-
转换工作正常,但是当它退出时,Monitor.Exit 抛出异常并且不释放......
标签: c# multithreading exception thread-safety monitor