Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 类之间的锁共享_C#_Multithreading_Locking - Fatal编程技术网

C# 类之间的锁共享

C# 类之间的锁共享,c#,multithreading,locking,C#,Multithreading,Locking,我试图找到在多个类之间共享锁文件的最佳实践。在此之前,我将多个函数放在同一个类中,这样它们就可以共享一个互锁文件和生产者/消费者队列。代码比我想要的要长一点,我想把它们分成单独的类。执行此操作时,我无法共享锁定文件或添加/删除命令的队列 我需要一个UI线程来接受用户的输入,然后将命令放入工作线程可以从中提取的锁定队列中。我想将UI线程和worker函数放在不同的类中,以保持代码的良好组织 对不起,如果这太模糊了。有没有一种方法不破坏良好的设计技术?如果锁在多个类之间共享,并且“所有者”不容易识别

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

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


对不起,如果这太模糊了。有没有一种方法不破坏良好的设计技术?

如果锁在多个类之间共享,并且“所有者”不容易识别,那么将这些锁放入共享的类中

public class MyLocks { ... all your locks ... }
然后,在初始化使用锁的类时,将它们传递到构造函数中。或者,您可以让类自己实例化mylock,然后将其作为属性公开,然后在后续构造中使用

...
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);

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

您可以使用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();
ConcurrentQueue workItems=新的ConcurrentQueue();
UIThreadClass uiThread=新的UIThreadClass(工作项);
WorkerThreadClass workerThread=新的workerThread(工作项);
uiThread.Run();
workerThread.Run();
在worker线程类中,可以定期检查工作项队列 使用方法TryPeek()查找新项。有关 ConcurrentQueue请参阅


希望,这有帮助。

什么是“锁定文件”?您正在使用FileStream/Unlock方法吗?如果是这样,你可能会考虑你是否真的需要它们。 回到锁定:我认为在大多数情况下(以及您的情况下),一个简单的、共享的()应该可以。Michael概述了基本想法-您应该在其上添加一个-它将大大简化您的项目和生活(无需传递实例,更易于调试)

小心那些线程,死锁不是好玩的


PS:这可能(对某些人)很明显,但锁只在处理多个线程时有效。

对不起,我指的是锁变量,例如只读对象workLock=new object();非常感谢。看到你对死锁的评论,我想起了一个集中式类,它允许人们在对锁进行故障排除时更加谨慎——特别是允许一个人按顺序获取锁,并且只按顺序释放。这就是我想使用的,但是读到以这种方式传递锁文件并不是一个好的设计。。我认为对于一个只有工作队列被锁定的项目来说,这并不是什么大问题。如果两个类紧密耦合,以至于它们知道彼此的锁,那么它们实际上是作为一个可测试单元运行的。有一些技巧可以通过接口和嵌套类向公众隐藏锁的实现,但这可能有些过分。实际上,我通过创建一个提交到队列的工作项来最小化所需的锁的数量。队列被一个线程占用,当轮到提交者时,该线程向提交者发出调用,从而避免了回调函数获取任何锁的需要。当然,这完全取决于你在做什么。