[英]How to transfer locks between threads?
我想要
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的所有權回阿爾法,喚醒並不斷與它的顯示器的所有權運行。
如果你完全不清楚,那么(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;
}
}
一種替代方法是使用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和排隊的線程鎖之間鎖定this.StaticLock
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.