2016-11-29 83 views
1

我的情景:C#中的一個線程鎖定,打電話給在另一個線程釋放

  • 幾個BackgroundWorkers執行各種功能。
  • 其中之一,只有一次,將不得不執行先做一項特殊工作,然後繼續並讓其他工作去完成他們的工作。

我正在使用Monitor.TryEnter:當這是真的(鎖定成功)做這個特殊的工作;當它是假的時候,會等待鎖被釋放。

問題是這項特殊工作是異步完成的。我有一個偵聽器,並且將調用CompletedSpecialWork方法,但是線程與執行Monitor.TryEnter的線程不同(即,線程保持(鎖定)對象)。我需要一種方法能夠發送消息到原始線程,要求釋放該對象。

我試圖讓一個靜態對象SynchronizationContext,但是當我做threadHoldingLock = SynchronizationContext.Current它是空的(它是從BackgroundWorker被調用,能夠保持鎖)。

我的問題是:從這個CompletedSpecialWork背景/線程,我怎麼能發送到原來的線程(持有鎖)通過Monitor.Exit解除鎖定的請求?我需要一種方法來將Invoke發送到Monitor.Exit的原始線程上。

+0

使用[Semaphore](https://msdn.microsoft.com/en-us/library/system.threading.semaphore(v = vs.110).aspx)。檢查[這個答案](http://stackoverflow.com/questions/9201848/how-to-transfer-locks-between-threads)。 –

回答

3

嘗試使用ManualResetEvent或AutoResetEvent。
這些可以用來阻塞一個線程,然後(通過從正在運行的線程進入阻塞線程的函數調用)允許塊被重置。
它們是信號量頂部的語法糖,但我喜歡簡化的界面。 祝你好運!

+0

您的最後一行不是真的 - 事件是Windows內核級別的專用同步對象。請參閱https://msdn.microsoft.com/en-us/library/windows/desktop/ms686915(v=vs.85).aspx –

+0

@Niels,好點。我在C中進行交叉思考 - 這兩種機制都是爲了使線程脫離正在運行的線程隊列。 – Monza

4

由於它們本身的性質,像互斥體這樣的同步對象需要從獲取鎖的同一個線程中釋放。如果這個需求不存在,並且你的所有線程都可以隨機釋放所有線程中的所有鎖,那麼它幾乎會使任何類型的同步都會失敗。

您應該查看Event對象以發出線程之間的簡單脈衝信號。

+0

是的,我同意。然而,這項特殊工作是異步完成的,當它完成時,我處於不同的線程中。我需要向原始線程發送一條消息,通知它已完成,並且您可以解鎖對象。 – igorjrr

+0

這就是事件的原因 - 表示發生了某些事件;) –

相關問題