简体   繁体   English

C#在一个线程中锁定,在另一个线程中调用释放

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

My scenario:我的场景:

  • a few BackgroundWorkers to perform various functions.一些BackgroundWorkers来执行各种功能。
  • one of them, and only once, will have to execute to do a special work first before continue and letting other works to do their job.其中一个,并且只有一次,必须先执行一项特殊工作,然后才能继续并让其他工作完成他们的工作。

I'm using Monitor.TryEnter : do this special work when it's true (locking is successful);我正在使用Monitor.TryEnter :当它为真时做这个特殊的工作(锁定成功); when it's false, will wait for the lock to be released.当它为假时,将等待锁被释放。

Problem is that this special work is done asynchronously.问题是这项特殊工作是异步完成的。 I have a listener, and the CompletedSpecialWork method will be called, but the Thread is different from the Thread where Monitor.TryEnter was performed (that is, the Thread holding(locking) the object).我有一个监听器,会调用CompletedSpecialWork方法,但 Thread 与执行Monitor.TryEnter的 Thread 不同(即持有(锁定)对象的 Thread)。 I need a way to be able to send a message to the original Thread asking to release the object.我需要一种方法来向原始线程发送消息,要求释放对象。

I tried to have a static object of SynchronizationContext , but when I do threadHoldingLock = SynchronizationContext.Current it is null (it is being called from the BackgroundWorker that was able to hold the lock).我试图拥有SynchronizationContext的静态对象,但是当我执行threadHoldingLock = SynchronizationContext.Current它为空(它是从能够保持锁定的 BackgroundWorker 调用的)。

My question is: from this CompletedSpecialWork context/thread, how can I send a request to the original thread (holding the lock) to release the lock via Monitor.Exit ?我的问题是:从这个CompletedSpecialWork上下文/线程,我如何向原始线程(持有锁)发送请求以通过Monitor.Exit释放锁? I need like a way to send a Invoke to the original thread with Monitor.Exit on it.我需要一种将 Invoke 发送到带有 Monitor.Exit 的原始线程的方法。

By their very nature synchronization objects like mutexes need to be released from the same thread that acquired a lock on them.就其本质而言,像互斥锁这样的同步对象需要从获得锁定它们的同一个线程中释放。 It would pretty much make any kind of synchronization a crashy hit&miss affair if this requirement didn't exist and all your threads could just randomly release all locks from all threads.如果这个要求不存在并且您的所有线程可以随机释放所有线程的所有锁,那么它几乎会使任何类型的同步成为一个崩溃的事件。

You should look at Event objects to signal simple pulses between threads.您应该查看 Event 对象以在线程之间发出简单的脉冲信号。

Try using either ManualResetEvent or AutoResetEvent.尝试使用 ManualResetEvent 或 AutoResetEvent。
These can be used to block one thread and then (via function call from a running thread into the blocked thread) allow the block to be reset.这些可用于阻塞一个线程,然后(通过从正在运行的线程到被阻塞线程的函数调用)允许重置该阻塞。
They are syntactic sugar on top of a Semaphore but I like the simplified interface.它们是信号量之上的语法糖,但我喜欢简化的界面。 Good luck!祝你好运!

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.

相关问题 锁定在一个线程中,在另一个线程中释放 - Locking in one thread, releasing in another 在C#中锁定线程 - Locking thread in C# C# 线程未释放 memory - C# Thread not releasing memory 带锁的 C# 线程池 - C# Thread Pool with Locking C# 线程锁定问题 - C# Thread Locking Problem 从另一个类(C#)调用线程 - Calling a thread from another class (C#) 从另一个线程C#调用UI线程 - Calling UI-thread from another thread C# 将UI Thread方法传递给另一个线程以便在C#中调用 - Passing UI Thread method to another thread for calling in C# c#从另一个线程调用backgroundWorker而不是UI线程 - c# calling backgroundWorker from another thread than UI thread 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
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM