gpt4 book ai didi

c# - 仅当线程处于某个方法时才锁定多个方法

转载 作者:太空宇宙 更新时间:2023-11-03 14:36:06 25 4
gpt4 key购买 nike

我有一个类(简化示例):

public class SomeCollection : ICloneable
{
public void Add(Item item) { /* ... */ }
public void Remove(Item item) { /* ... */ }
public Item Get(Key key) { /* ... */ }
/*
...
*/
public object Clone() { /* ... */ }
}

我需要当一个线程进入 Clone() 时,其他线程不能进入 Add 或 Remove,但可以进入 Get。起初我想到了:

    public void Add(Item item) { lock(addLock) { /* ... */ } }
public void Remove(Item item) { lock(removeLock) { /* ... */ } }

public object Clone(Item item)
{
lock(addLock)
{
lock(removeLock)
{
/* ... */
}
}
}

这可行(我认为)但有一些缺点:* 我不希望两个线程进入 Add 相互阻塞——我正在处理更深层次的代码* 我将不得不承受每次调用 Add 或 Remove 的锁定开销

然后我想到了这个

    private volatile bool cloning = false; // notice the volatile keyword

public void Add(Item item)
{
int i = 0;
while(cloning)
{
if (i++ > 20)
throw new TimeoutException();
Thread.Sleep(50); // waits 50 milliseconds
}
/* ... */
} // and the same for Remove

public object Clone()
{
cloning = true;
try
{
/* do the cloning */
} finally { cloning = false; }
}

但是这种方法:

  • 更复杂
  • Clone 可以在一个线程还没有执行完 Add 或 Remove 时进入
  • 看起来不自然

我给了ReadWriterLockSlim看一眼,但似乎不适合我的场景。

我需要这个,因为 Clone 方法需要很长时间(可能需要一秒钟 - 集合是巨大的)并且在这段时间内进行更改会破坏枚举器(在 foreach 循环中使用)。是的,我必须使用 foreach,因为底层 key 集合除了 IEnumerable 外不公开任何其他内容。

会推荐什么?

最佳答案

您能否详细解释一下为什么 ReaderWriterLockSlim 不适合您的场景?

当然,您不会因为它的经典用法而使用它,但将 Clone 方法视为您的编写者,将添加/删除方法视为您的读者,我认为它很合适。

[edit] 另一件事:如果你走这条路,请确保记录你为什么“向后”使用 ReaderWriterLockSlim,以便下一个阅读代码的人(或六个月后的你)理解发生了什么。

关于c# - 仅当线程处于某个方法时才锁定多个方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1014130/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com