如何在线程之间传递锁
本文关键字:之间 线程 | 更新日期: 2023-09-27 18:23:54
我想
Monitor.Enter(this.StaticLock);
try
{
// Do something ...
ThreadPool.QueueUserWorkItem(state =>
{
try
{
// Do something else...
}
finally
{
Monitor.Exit(this.StaticLock);
}
});
}
catch (Exception)
{
Monitor.Exit(this.StaticLock);
throw;
}
但它不起作用,因为它不能对当前线程中不是Monitor.Enter
的对象执行Monitor.Exit
。如何做到这一点?我应该使用线程间通信吗?
如何在线程之间传递锁?
您在初始线程上输入监视器,例如线程Alpha。任何试图进入监视器的其他线程都将被阻止,直到监视器可用。
如果您想将锁转移到另一个线程,比如线程Bravo,同时在Bravo完成后仍然能够恢复线程Alpha并拥有监视器的所有权,那么您可以在监视器上将Alpha置于等待状态。如果线程Bravo在监视器上被阻塞,则它会唤醒并进入监视器。完成后,脉冲监视器,这将放弃Bravo对监视器的所有权,并将所有权转移回Alpha,Alpha会醒来并继续运行监视器的所有权。
如果你完全不清楚这一点,那么(1)你一开始就不应该试图这样做;如果你弄错了,这是非常危险的,(2)你应该读一下:
http://www.codeproject.com/Articles/28785/Thread-synchronization-Wait-and-Pulse-demystified
Semaphore
允许您将它们锁定在一个线程中,并在另一个线程解锁。
但是这种行为对我来说很可疑……你到底想实现什么?在实践中几乎不应该这样做。
static readonly Semaphore semaphore = new Semaphore(1, 1);
void Method1()
{
semaphore.WaitOne();
try
{
// Do something ...
new Thread(() =>
{
try
{
// Do something else...
}
finally
{
semaphore.Release();
}
}).Start();
}
catch (Exception)
{
semaphore.Release();
throw;
}
}
您可以为此使用Mutex。它们就像锁,但有更多的特点。它们也更贵。
你肯定已经知道,你在这里处于危险的境地。在线程之间传递锁是危险的。。。
一种选择是使用WaitHandle
var waitHandle = new AutoResetEvent(initialState: false);
ThreadPool.QueueUserWorkItem(state =>
{
lock(this.staticLock)
{
try
{
// Do something ...
}
finally
{
waitHandle.Set();
}
// Do something else...
}
}
waitHandle.WaitOne();
如果Eric Lippert的答案适合我,我会实现:
lock(this.StaticLock)
{
ThreadPool.QueueUserWorkItem(state =>
{
lock(this.StaticLock)
{
// Do something ...
Monitor.Pulse(this.StaticLock);
// Do something else...
}
});
Monitor.Wait(this.StaticLock);
}
不幸的是,这个解决方案并不能阻止另一个线程锁定它。Monitor.Wait和排队线程锁定之间的StaticLock