我有一个需要运行独占运行代码块的方法,但我只想在确实需要时添加此限制。根据 Id 值(一个 Int32),我将加载/修改不同的对象,因此锁定所有线程的访问是没有意义的。这是这样做的第一次尝试-
private static readonly ConcurrentDictionary<int, Object> LockObjects = new ConcurrentDictionary<int, Object>();
void Method(int Id)
{
lock(LockObjects.GetOrAdd(Id,new Object())
{
//Do the long running task here - db fetches, changes etc
Object Ref;
LockObjects.TryRemove(Id,out Ref);
}
}
我怀疑这是否可行 - TryRemove 可能会失败(这将导致 ConcurrentDictionary 不断变大)。
一个更明显的错误是 TryRemove 成功删除了 Object 但如果有其他线程(对于相同的 Id)正在等待(锁定)这个对象,然后一个具有相同 Id 的新线程进来并添加一个新的对象并开始处理,因为没有其他人在等待它刚刚添加的对象。
我应该使用 TPL 还是某种 ConcurrentQueue 来代替我的任务?最简单的解决方案是什么?