c# - 锁字典不断增长,不知如何清理?

标签 c# data-structures locking memory-management race-condition

我有一个基于 Web 的商品订购系统。

  • 商品限时,售卖 Y 小时
  • 每件商品只允许 X 个订单

为了保持每件商品的订单 <= X,我使用了这种锁定机制。

private static Dictionary<Guid, Object> PurchaseLockDictionary = null;

private static object GetLock(Guid itemId)
    {
        if (!PurchaseLockDictionary.ContainsKey(itemId))
        {
            PurchaseLockDictionary.Add(itemId, new object());
        }
        return PurchaseLockDictionary[itemId];
    }

购买看起来像这样:

public static Order Purchase(Buyer buyer, OrderItem item)
    {
        Order order;
        try
        {
            lock (GetLock(item.Id))
            {
                // order stuff like counting current amount of orders, buyer validity etc
            }
        } catch (Exception e) {
            // Exception stuff
        }
        return order;
    }

现在,我的问题是,如何防止锁定机制(Dictionary 对象)超出比例?目前我们出于其他原因每周重新启动一次服务器,但我不希望代码依赖于这种行为。

是否有另一种数据结构更适合这种锁机制?或者是否有一种聪明的方法来查找和清理词典中的旧条目?非常欢迎提出想法!

最佳答案

using (var locker = new PurchaseLocker(item.Id))
{
    // order stuff like counting current amount of orders, buyer validity etc
}

// ...

public sealed class PurchaseLocker : IDisposable
{
    private static readonly object _bigLock = new object();
    private static readonly Dictionary<Guid, LockToken> _lockMap = new Dictionary<Guid, LockToken>();
    private readonly Guid _itemId;

    public PurchaseLocker(Guid itemId)
    {
        _itemId = itemId;

        LockToken miniLock;
        lock (_bigLock)
        {
            if (!_lockMap.TryGetValue(itemId, out miniLock))
            {
                miniLock = new LockToken();
                _lockMap.Add(itemId, miniLock);
            }
            miniLock.Count++;
        }
        Monitor.Enter(miniLock);
    }

    public void Dispose()
    {
        lock (_bigLock)
        {
            LockToken miniLock = _lockMap[_itemId];
            miniLock.Count--;
            if (miniLock.Count == 0)
                _lockMap.Remove(_itemId);

            Monitor.Exit(miniLock);
        }
    }

    private sealed class LockToken
    {
        public int Count;
    }
}

关于c# - 锁字典不断增长,不知如何清理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5820507/

相关文章:

c - 不使用数组从 n 个数中取最大的三个数

node.js - Node Redis - 使用 EX 和 NX 设置?

mysql - Mysql Gap-lock/Next-key Locks规则

c# - 空合并参数给出意外警告

c# - 从 Azure 获取用户的个人资料图片

java - 如何在哈希表中搜索多个键

java - 一种有效索引数千个移动点的数据结构?

terminal - 如何删除本地 npm 安装的 sudo 要求?

c# - 获取全局目录的 PrincipalContext 的连接服务器

c# - 具有同步和异步调用者的同步方法中的 Thread.Sleep 或 Task.Delay