锁类之间的共享

时间:2011-08-14 16:01:29

标签: c# multithreading locking

我正在尝试找到在多个类之间共享锁文件的最佳实践。在此之前,我将多个函数放在同一个类中,因此它们可以共享一个相互锁定文件和一个生产者/消费者队列。代码比我想要的要长一些,我想把它们分成几个单独的类。当我这样做时,我无法共享锁文件或队列来添加/删除命令。

我需要一个接受用户输入的UI线程,然后将命令放入工作线程可以从中拉出的锁定队列中。我想将UI线程和worker函数放在不同的类中,以保持我的代码组织良好。

很抱歉,如果这太模糊了。有没有办法做到这一点,不破坏良好的设计技术?

3 个答案:

答案 0 :(得分:2)

如果锁在多个类之间共享,并且“owner”不易识别,则将这些锁放入共享的类中。

public class MyLocks { ... all your locks ... }

然后,在初始化使用锁的类时,将它们传递给构造函数。或者,您可以让类自己实例化MyLocks,然后将其作为属性公开,然后您可以在后续构造中使用它。

...
var a = new ClassWithLocks();
var b = new ClassWithLocks(a.MyLocks);
var b = new SomeOtherClassWithLocks(a.MyLocks);
...

要点是把锁放在自己的单位里。

<强>更新

将多个锁放入其自己的类中的另一个好处是,您可以显式创建用于占用和释放锁的方法。例如:

void PushLock(string myToken, LOCK_ENUM theLockIWant);
void PopLock(string myToken, LOCK_ENUM theLockIWant);

现在一个特定的类或操作可以请求锁定,但是如果它们试图获取一个锁定,其枚举数小于它们请求的锁定,则可以抛出异常。当您需要多个锁来执行操作时,这很重要,因为您可以确保按顺序获取和释放锁,这是死锁中最常见的罪魁祸首之一。

答案 1 :(得分:1)

您可以使用System.Collection.Concurrent命名空间中的线程安全ConcurrentQueue,并在您的UI线程和工作线程之间共享此队列,如下所示:

ConcurrentQueue<T> workItems = new ConcurrentQueue<T>();

UIThreadClass uiThread = new UIThreadClass(workItems);

WorkerThreadClass workerThread = new WorkerThread(workItems);

uiThread.Run();

workerThread.Run();

在您的工作线程类中,您可以定期检查工作项队列 使用TryPeek()方法获取新项目。有关详细说明 ConcurrentQueue参考MSDN

希望,这有帮助。

答案 2 :(得分:0)

什么是'锁定文件'?您使用的是FileStream Lock / Unlock方法吗?如果是这样,你可能会考虑是否真的需要它们。

回到锁定:我认为在大多数情况下(和你的),我应该做一个简单的共享ReaderWriterLockSlim)。迈克尔概述了基本思想 - 你应该在其上添加一个singleton - 它会简化你的项目和生活(不需要传递实例,更容易调试)。

小心那些线程,死锁并不好玩!

PS:对某些人来说可能是显而易见的,但锁只在处理多个线程时才有效。