如何在线程之间传输锁?
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.Exit
的对象,这不是在当前线程Monitor.Enter
上。怎么做?我应该使用线程间通信吗?
Semaphore
s允许您将它们锁定在一个线程中并在另一个线程中解锁它们。
但是这种行为对我来说是非常可疑的......你究竟在做什么?这在实践中几乎不应该做。
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;
}
}
我想过使用'SemaphoreSlim',但它是专为短暂的等待期 – 2012-02-09 12:06:52
您可以为此使用Mutexes。它们就像锁,但具有更多的功能。他们也更昂贵。
正如你一定已经知道,你在这里是危险的领土。跨线程传递锁定是危险的...
如何在线程之间转移锁吗?
你在初始线程上输入显示器,比如线程Alpha。尝试进入显示器的任何其他线程都会阻塞,直到显示器可用。
然后,如果您想锁转移到另一个线程,说线程布拉沃,同时仍然能够恢复线程阿尔法与显示器时布拉沃做的所有权,然后你把阿尔法在等待状态在显示器上。如果线程布拉沃是阻止在监视器上然后醒来,进入监视器。当它完成时,它会丢弃显示器,它放弃了Bravo对显示器的所有权,并将所有权转移回Alpha,后者醒来并继续以显示器的所有权运行。 (1)你不应该试图在第一时间做到这一点;但是,如果你完全不清楚这一点,
http://www.codeproject.com/Articles/28785/Thread-synchronization-Wait-and-Pulse-demystified
如果埃里克Lipert的回答适合我,我会实现:如果你弄错了,和(2)你应该阅读这是超级危险的
lock(this.StaticLock)
{
ThreadPool.QueueUserWorkItem(state =>
{
lock(this.StaticLock)
{
// Do something ...
Monitor.Pulse(this.StaticLock);
// Do something else...
}
});
Monitor.Wait(this.StaticLock);
}
不幸的是这个解决方案没有按”防止另一个线程锁定this.StaticLock Monitor.Wait和队列之间的线程锁
一种替代方法是使用WaitHandle
var waitHandle = new AutoResetEvent(initialState: false);
ThreadPool.QueueUserWorkItem(state =>
{
lock(this.staticLock)
{
try
{
// Do something ...
}
finally
{
waitHandle.Set();
}
// Do something else...
}
}
waitHandle.WaitOne();
你可能做错了什么。这是什么用例? – 2012-02-08 21:37:40
为什么不把'Monitor.Enter'放在工作项目内? – Yahia 2012-02-08 21:39:37
是否有你无法锁定queueUserWorkItem委托内的对象的原因? (您可以锁定然后解锁项目,以便/ *做某些事情* /如果需要排队该项目之前发生的事情。) – Servy 2012-02-08 21:40:09