gpt4 book ai didi

c# - 在每个项目的基础上同步线程

转载 作者:行者123 更新时间:2023-12-03 12:59:48 25 4
gpt4 key购买 nike

尽管这个问题是关于MemoryCache类的,但我可以想象DictionaryConcurrentDictionary.GetOrAdd的需求相同,其中valueFactory -lambda也是一个冗长的操作。

本质上,我想在每个项目的基础上同步/锁定线程。我知道MemoryCache是线程安全的,但是仍然需要检查项目是否存在并在不存在时添加该项目,仍然需要进行同步。

考虑以下示例代码:

public class MyCache
{
private static readonly MemoryCache cache = new MemoryCache(Guid.NewGuid().ToString());

public object Get(string id)
{
var cacheItem = cache.GetCachedItem(id);
if (cacheItem != null) return cacheItem.Value;
var item = this.CreateItem(id);
cache.Add(id, item, new CacheItemPolicy
{
SlidingExpiration = TimeSpan.FromMinutes(20)
});
return item;
}

private object CreateItem(string id)
{
// Lengthy operation, f.e. querying database or even external API
return whateverCreatedObject;
}
}

如您所见,我们需要同步 cache.GetCachedItemcache.Add。但是由于 CreateItem是一个冗长的操作(因此 MemoryCache),所以我不想像此代码那样锁定所有线程:
public object Get(string id)
{
lock (cache)
{
var item = cache.GetCachedItem(id);
if (item != null) return item.Value;
cache.Add(id, this.CreateItem(id), new CacheItemPolicy
{
SlidingExpiration = TimeSpan.FromMinutes(20)
});
}
}

同样,不锁定也不是一种选择,因为这样我们可以有多个线程为同一个 CreateItem调用 id

我所能做的就是为每个 Semaphore创建一个唯一的名为 id的代码,因此锁定是在每个项目的基础上进行的。但这将是系统资源的杀手,因为我们不想在我们的系统上注册+ 100K命名信号量。

我确定我不是第一个需要这种同步的人,但是我没有找到适合这种情况的任何问题/答案。

我的问题是,是否有人可以针对此问题提出不同的,资源友好的方法?

更新

我发现 this NamedReaderWriterLocker 类乍看起来很有希望,但使用起来很危险,因为当两个线程同时进入 ReaderWriterLockSlimConcurrentDictionary时,两个线程可能会使用相同名称的另一个 valueFactory实例。也许我可以将此实现与 GetLock方法内的一些附加锁一起使用。

最佳答案

由于您的 key 是字符串,因此您可以锁定string.Intern(id)

MSDN文档:System.String.Intern

IE。

lock (string.Intern(id))
{
var item = cache.GetCachedItem(id);
if (item != null)
{
return item.Value;
}

cache.Add(id, this.CreateItem(id), new CacheItemPolicy
{
SlidingExpiration = TimeSpan.FromMinutes(20)
});

return /* some value, this line was absent in the original code. */;
}

关于c# - 在每个项目的基础上同步线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36839135/

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