gpt4 book ai didi

c# - 如何在包含 C# 对象列表的字典上使用锁?

转载 作者:行者123 更新时间:2023-11-30 22:40:12 25 4
gpt4 key购买 nike

我有以下类(class):

public static class HotspotsCache
{
private static Dictionary<short, List<HotSpot>> _companyHotspots = new Dictionary<int, List<HotSpot>>();
private static object Lock = new object();


public static List<HotSpot> GetCompanyHotspots(short companyId)
{
lock (Lock)
{
if (!_companyHotspots.ContainsKey(companyId))
{
RefreshCompanyHotspotCache(companyId);
}

return _companyHotspots[companyId];
}
}

private static void RefreshCompanyHotspotCache(short companyId)
{
....

hotspots = ServiceProvider.Instance.GetService<HotspotsService>().GetHotSpots(..);
_companyHotspots.Add(companyId, hotspots);

....
}

我遇到的问题是,在 RefreshCompanyHotspotCache 方法中获取热点的操作需要花费大量时间。因此,当一个线程正在为某个 CompanyId 执行缓存刷新时,所有其他线程都在等待此操作完成,尽管可能有线程正在请求另一个 companyId 的热点列表,而该列表已经加载到字典。我希望不要锁定这些最后的线程。我还希望所有请求尚未加载到缓存中的公司的热点列表的线程等待列表被完全检索并加载到字典中。

有没有办法只锁定正在读取/写入特定 companyId(正在刷新)缓存的线程,而让正在为另一家公司请求数据的其他线程完成它们的工作?

我的想法是使用和锁数组

lock (companyLocks[companyId])
{
...
}

但这并没有解决任何问题。与一家公司打交道的线程仍在等待为其他公司刷新缓存的线程。

最佳答案

使用 Snowbear 也提到的双重检查锁定机制 - 这将防止您的代码在实际上不需要锁定时锁定。

根据您关于每个客户端单独锁的想法,我过去使用过这种机制,尽管我使用了锁字典。我制作了一个实用程序类,用于从 key 中获取锁对象:

/// <summary>
/// Provides a mechanism to lock based on a data item being retrieved
/// </summary>
/// <typeparam name="T">Type of the data being used as a key</typeparam>
public class LockProvider<T>
{
private object _syncRoot = new object();
private Dictionary<T, object> _lstLocks = new Dictionary<T, object>();

/// <summary>
/// Gets an object suitable for locking the specified data item
/// </summary>
/// <param name="key">The data key</param>
/// <returns></returns>
public object GetLock(T key)
{
if (!_lstLocks.ContainsKey(key))
{
lock (_syncRoot)
{
if (!_lstLocks.ContainsKey(key))
_lstLocks.Add(key, new object());
}
}
return _lstLocks[key];
}
}

所以只需按以下方式使用它...

private static LockProvider<short> _clientLocks = new LockProvider<short>();
private static Dictionary<short, List<HotSpot>> _companyHotspots = new Dictionary<short, List<HotSpot>>();

public static List<HotSpot> GetCompanyHotspots(short companyId)
{
if (!_companyHotspots.ContainsKey(companyId))
{
lock (_clientLocks.GetLock(companyId))
{
if (!_companyHotspots.ContainsKey(companyId))
{
// Add item to _companyHotspots here...
}
}
return _companyHotspots[companyId];
}

关于c# - 如何在包含 C# 对象列表的字典上使用锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5358651/

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