这个哈希集锁线程安全吗?

Is this Hashset lock threadsafe?


private static readonly object MyMethodLockobject = new object();
private static readonly HashSet<long> ActiveWorkItem = new HashSet<long>();


public async Task MyMethod(long id)
{
    lock (MyMethodLockobject)
    {
        if (ActiveWorkItem.Contains(id))
        {
            throw new AnotherRequestAlreadyInProgressException();
        }

        ActiveWorkItem.Add(id);
    }

    try
    {
        return await DoWork(id);
    }
    finally
    {
        ActiveWorkItem.Remove(id);
    }
}

ActiveWorkItem 的目的是防止对同一 ID 进行并发调用。只需要添加包含和删除。 MyMethod 是唯一具有 ActiveWorkItem 访问权限的地方。

我关心的是这一行:

    finally
    {
        ActiveWorkItem.Remove(id);
    }

或有必要改为

    finally
    {
        lock (MyMethodLockobject)
            {
                ActiveWorkItem.Remove(id);
            }
    }

更好的选择也很受欢迎

是的,finally块里面的HashSet也是需要保护的

finally
{
    lock (MyMethodLockobject) ActiveWorkItem.Remove(id);
}

否则,一个线程可能正在向 HashSet 添加项目,而多个线程同时从同一个 HashSet 中删除项目,可能会使对象处于损坏状态,并导致未定义的行为。