簡體   English   中英

如何在線程之間傳輸鎖?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM