【发布时间】:2026-01-26 00:20:07
【问题描述】:
这里的问题是:如果一个线程获得一个对象的独占锁——例如通过使用Monitor.Enter——被终止,这是否会神奇地释放该对象上的独占锁?如果这是真的,那么假设我们从另一个线程调用Monitor.Exit——因为我们假设对象被锁定——那不是会抛出SynchronizationLockException 类型的异常吗?
我不确定这是预期的行为还是错误...
为了演示这个问题,我创建了一段简单的代码,它调用 Monitor.TryEnter 而不在 System.Timers.Timer.Elapsed 事件回调中调用 Monitor.Exit “请注意,Timers.Timer 类在内部使用 ThreadPool 来运行回调事件处理程序,并且它可能每次都在来自池的不同线程上调用经过的回调。”
class Foo
{
private System.Timers.Timer _timer = new System.Timers.Timer(2000);//every 2s
private static readonly object _locker = new object();//static locker object
public Foo()
{
_timer.Elapsed += delegate
{
if (Monitor.TryEnter(_locker))//acquiring the lock without calling Exit..
{
Console.WriteLine(string.Format("Access Succeed!!, Thread Id {0}",
Thread.CurrentThread.ManagedThreadId));
Thread.Sleep(6000);//simulate a work for 6 seconds
}
else
{
Console.WriteLine(string.Format("Unable to access to locker method within locker object, Thread Id {0}",
Thread.CurrentThread.ManagedThreadId));
}
};
_timer.Start();
}
}
//to test: just initialize a new instance of foo class
Foo foo = new Foo();
//blocks until application is terminated..
Thread.Sleep(Timeout.Infinite);
输出窗口显示结果:
Access Succeed!!, Thread Id 11
Unable to access to locker method within locker object, Thread Id 12
Unable to access to locker method within locker object, Thread Id 12
Access Succeed!!, Thread Id 11
Unable to access to locker method within locker object, Thread Id 12
Unable to access to locker method within locker object, Thread Id 12
Unable to access to locker method within locker object, Thread Id 12
Unable to access to locker method within locker object, Thread Id 12
Access Succeed!!, Thread Id 11
Unable to access to locker method within locker object, Thread Id 12
Unable to access to locker method within locker object, Thread Id 12
....
【问题讨论】:
标签: c# .net multithreading timer locking