簡體   English   中英

C#在一個線程中鎖定,在另一個線程中調用釋放

[英]C# locking in one thread, calling to releasing in another thread

我的場景:

  • 一些BackgroundWorkers來執行各種功能。
  • 其中一個,並且只有一次,必須先執行一項特殊工作,然后才能繼續並讓其他工作完成他們的工作。

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

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

我試圖擁有SynchronizationContext的靜態對象,但是當我執行threadHoldingLock = SynchronizationContext.Current它為空(它是從能夠保持鎖定的 BackgroundWorker 調用的)。

我的問題是:從這個CompletedSpecialWork上下文/線程,我如何向原始線程(持有鎖)發送請求以通過Monitor.Exit釋放鎖? 我需要一種將 Invoke 發送到帶有 Monitor.Exit 的原始線程的方法。

就其本質而言,像互斥鎖這樣的同步對象需要從獲得鎖定它們的同一個線程中釋放。 如果這個要求不存在並且您的所有線程可以隨機釋放所有線程的所有鎖,那么它幾乎會使任何類型的同步成為一個崩潰的事件。

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

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

C# 多線程 - 列表<object>當另一個線程正在處理列表時鎖定線程中的列表<div id="text_translate"><p>我的程序有 2 個主線程:</p><ol><li> Thread checkForNewItemsThread將新對象添加到volatile List&lt;Object&gt;</li><li> Thread workOnListThread在List&lt;Object&gt;上工作,並為列表中需要工作的每個項目創建另一個新Thread doWorkThread 。</li></ol><p> 我在workOnListThread期間遇到了 ArgumentNull 異常,因為(我認為正在發生的事情)要么:</p><ol><li> 我的checkForNewItemsThread正在添加到列表中,而workOnListThread正在遍歷列表。</li><li> 一旦完成對 object 的處理,我的doWorkThread就會從列表中刪除該項目。</li></ol><p> 我相信正確的做法是在workOnListThread在列表上工作時鎖定List&lt;Object&gt; List&lt;Object&gt;的正確位置List&lt;Object&gt; ,我認為這應該是正確的,但是可以使用一些指導。</p><pre> volatile List&lt;Object&gt; List1 = new List&lt;Object&gt;(); private static readonly object _lock = new object(); Thread checkForNewItemsThread; Thread workOnListThread; Thread doWorkThread; public void OnTimerCheckNewItems(object sender, ElapsedEventArgs args) { List&lt;Object&gt; List1Temp = new List&lt;Object&gt;(); List1Temp = getList(); addNewItems(List1Temp); } private void addNewItems(List&lt;Object&gt; list) { foreach (Object obj in list) { if (.List1.Any(o =&gt; o.ID == obj.ID)) //check if object already exists { List1;Add(obj). } } } private void workOnList() { while (true) //loop forever { while (List1;Count.= 0) //while items exist { lock (_lock) //lock while iterating through list { try { for (int i = 0; i &lt; List1.Count. i++) { if (List1[i];Status == Status.ready &amp;&amp; List1[i];= null) { doWorkThread = new Thread(() =&gt; doWork(List1[i])). doWorkThread;Start(). Thread.Sleep(3000). // wait for process to start } } } catch (Exception e) { Console,WriteLine(DateTime:Now,ToString(); ". "; e). Log(e;ToString()). } } } } } private void doWork(Object obj) { lock (_lock) //lock during update to status { int i = List.IndexOf(obj); List1[i].Status = Status;pending; } //work done here List1.Remove(alert); }</pre></div></object>

[英]C# MultiThreading - List<Object> Locking a list from a thread while another thread is working on the list

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

相關問題 鎖定在一個線程中,在另一個線程中釋放 在C#中鎖定線程 C# 線程未釋放 memory 帶鎖的 C# 線程池 C# 線程鎖定問題 從另一個類(C#)調用線程 從另一個線程C#調用UI線程 將UI Thread方法傳遞給另一個線程以便在C#中調用 c#從另一個線程調用backgroundWorker而不是UI線程 C# 多線程 - 列表<object>當另一個線程正在處理列表時鎖定線程中的列表<div id="text_translate"><p>我的程序有 2 個主線程:</p><ol><li> Thread checkForNewItemsThread將新對象添加到volatile List&lt;Object&gt;</li><li> Thread workOnListThread在List&lt;Object&gt;上工作,並為列表中需要工作的每個項目創建另一個新Thread doWorkThread 。</li></ol><p> 我在workOnListThread期間遇到了 ArgumentNull 異常,因為(我認為正在發生的事情)要么:</p><ol><li> 我的checkForNewItemsThread正在添加到列表中,而workOnListThread正在遍歷列表。</li><li> 一旦完成對 object 的處理,我的doWorkThread就會從列表中刪除該項目。</li></ol><p> 我相信正確的做法是在workOnListThread在列表上工作時鎖定List&lt;Object&gt; List&lt;Object&gt;的正確位置List&lt;Object&gt; ,我認為這應該是正確的,但是可以使用一些指導。</p><pre> volatile List&lt;Object&gt; List1 = new List&lt;Object&gt;(); private static readonly object _lock = new object(); Thread checkForNewItemsThread; Thread workOnListThread; Thread doWorkThread; public void OnTimerCheckNewItems(object sender, ElapsedEventArgs args) { List&lt;Object&gt; List1Temp = new List&lt;Object&gt;(); List1Temp = getList(); addNewItems(List1Temp); } private void addNewItems(List&lt;Object&gt; list) { foreach (Object obj in list) { if (.List1.Any(o =&gt; o.ID == obj.ID)) //check if object already exists { List1;Add(obj). } } } private void workOnList() { while (true) //loop forever { while (List1;Count.= 0) //while items exist { lock (_lock) //lock while iterating through list { try { for (int i = 0; i &lt; List1.Count. i++) { if (List1[i];Status == Status.ready &amp;&amp; List1[i];= null) { doWorkThread = new Thread(() =&gt; doWork(List1[i])). doWorkThread;Start(). Thread.Sleep(3000). // wait for process to start } } } catch (Exception e) { Console,WriteLine(DateTime:Now,ToString(); ". "; e). Log(e;ToString()). } } } } } private void doWork(Object obj) { lock (_lock) //lock during update to status { int i = List.IndexOf(obj); List1[i].Status = Status;pending; } //work done here List1.Remove(alert); }</pre></div></object>
 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM