首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#并发、锁定和字典对象

C#并发、锁定和字典对象
EN

Stack Overflow用户
提问于 2009-01-13 21:52:49
回答 4查看 6K关注 0票数 0

我有一堆加载到DB对象中的DB实体。相同的DB实体可以加载到多个DB对象中。数据库实体需要定期进行特殊处理。此处理必须一次由一个线程执行。锁定在这里是按顺序的。

编辑:重要注意事项:该流程调用速度较慢的web服务。这就是我试图阻止并发的原因。我不明白如何在没有锁的情况下安全地做到这一点。

因此,我创建了一个“padlock”对象,DB对象将引用该对象以进行锁定。挂锁对象是基于实体的,因此同一实体的两个或多个DB对象将使用相同的挂锁对象。我使用DB实体的ID作为键,将这些挂锁存储在一个字典对象中。padlock对象也只是一个简单的string对象。这是正确的方法吗?我在想,我要么过度工程,要么简化了这件事。如果这种方法是正确的,那么这段代码是什么样子的?它可以工作,但我还没有在负载下测试它。

谢谢:)

代码语言:javascript
复制
public static func(CustomObject o)
{
    if (ReadyForUpdate(o))
    {
        lock (LookupPadLockByID(object.ID)
        {
            if (ReadyForUpdate(o))
            {
                PerformUpdate(object);
            }
        }
    }
}

private static readonly object padlockLock = new object();
private static readonly Dictionary<int, string> padLocks = new Dictionary<int,string>();
private static object LookupPadLockByID(int uniqueID)
{
    lock (padlockLock)
    {
        if (!padLocks.ContainsKey(uniqueID))
        {
            padLocks.Add(uniqueID, uniqueID + " is locked");
        }
    }

    return padLocks[uniqueID];
}
EN

回答 4

Stack Overflow用户

发布于 2009-01-13 21:59:19

那么,您最终锁定了一个字符串,这不是一个好主意(尽管连接意味着实习不应该是一个大问题)。更大的问题是:

  • 您似乎没有从padLocks中移除锁-这是一个问题吗?
  • 您在padlockLock之外访问字典;return应该在return

对于第二个,这会更简单:

代码语言:javascript
复制
object itemLock;
if (!padLocks.TryGetValue(uniqueID, out itemLock)) {
    itemLock = new object();
    padLocks.Add(uniqueID, itemLock);
}
return itemLock;

如果这段代码是相当本地的(即你的对象还没有转义),你可以简单地lock记录本身?简单多了..。

票数 1
EN

Stack Overflow用户

发布于 2009-01-13 23:41:21

锁定字符串不是一个好主意。我建议两种选择:

  1. 使用Dictionary<int,object>作为padLocks类型,并将new object();作为值。
  2. 创建一个简单地保存id的类;如果您想在调试时查看LockPad类,这将提高可读性。

LockPad类:

代码语言:javascript
复制
class LockPad {
    public int Id { get; private set; }

    public LockPad(int id) {
        this.Id = id;
    }

    public override string ToString() {
        return "lock of " + id.ToString();
    }
}

然后,锁定那个类。

票数 1
EN

Stack Overflow用户

发布于 2009-01-13 22:05:01

我觉得你有点太过工程学了。如果你只需要保护你的DB实体(我假设在你的代码中用"object“来表示,我会把它改为"entity"),你可以把它当做你的锁。任何引用对象都可以用作锁:

代码语言:javascript
复制
public static func(CustomObject o)
{
    if (ReadyForUpdate(o))
    {
        lock (entity)
        {
                if (ReadyForUpdate(o))
                {
                        PerformUpdate(entity);
                }
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/440957

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档