我有一个供多个后台线程访问以更新/读取的列表。更新操作包括插入和删除。
为了同时执行此操作而没有同步问题,我在类中的私有只读对象上使用了锁定。
为了最大程度地减少读取列表数据时需要锁定列表的时间,我对其进行了深层克隆,然后返回该深层克隆并解锁字典以进行插入/删除更新。
因此,每次读取列表都会增加我的服务的内存消耗。
需要注意的一点是,插入/删除是包含列表的类的内部。但是阅读内容仅供公众使用。
我的问题是:
有什么办法,我可以避免克隆列表,而仍然使用读/写锁将其同时用于读取?
public class ServiceCache
{
private static List<Users> activeUsers;
private static readonly object lockObject = new object();
private static ServiceCache instance = new ServiceCache();
public static ServiceCache Instance
{
get
{
return instance;
}
}
private void AddUser(User newUser)
{
lock (lockObject)
{
//... add user logic
}
}
private void RemoveUser(User currentUser)
{
lock (lockObject)
{
//... remove user logic
}
}
public List<Users> ActiveUsers
{
get
{
lock (lockObject)
{
//The cache returns deep copies of the users it holds, not links to the actual data.
return activeUsers.Select(au => au.DeepCopy()).ToList();
}
}
}
}
最佳答案
听起来您需要使用ConcurrentDictionary
类,并为要存储的每个Users
对象创建一个密钥。然后,添加/更新用户就变得如此简单:
_dictionary.AddOrUpdate("key", (k, v) =>
{
return newUser;
}, (k, v) =>
{
return newUser;
});
然后删除,您将执行以下操作:
Users value = null;
_dictionary.TryRemove("key", out value);
获取人员列表也非常容易,因为您只需要这样做:
return _dictionary.Values.Select(x => x.Value).ToList();
那一刻应该返回字典内容的副本。
并让.NET运行时为您处理线程。
关于c# - 提高并发字典访问的效率C#,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10287141/