有关锁定的问题,文本引用下面的示例代码...我有一个类(Class1),它提供了一个名为Class1Resources的公共List属性。 Class1中的2个方法为Class1Resources提供基本查询功能。此外,Class1还订阅来自不同服务的事件,该事件提供Class1应更新此Class1Resources对象的通知。
我的问题是,应该实现锁定的内容和位置,以便在执行ExternalAppCallback时阻止查询Class1Resources的2个公共方法,从而确保查询方法始终使用最新数据?我在ExternalAppCallback中使用的注释代码是正确的方法吗?
public class Class1
{
public List<Resource> Class1Resources { get; private set; }
public Class1()
{
// subscribe to external app event, with callback = ExternalAppCallback
}
private void ExternalAppCallback(List<Resource> updatedResourceList)
{
// do I put the lock here as in the code below?
//lock(someObject)
//{
// Class1Resources = new List<Resource>(updatedResourceList);
//}
Class1Resources = new List<Resource>(updatedResourceList);
}
public List<Resource> GetResourcesByCriteria1(string criteria1)
{
return Class1Resources.Where(r => r.Criteria1 == criteria1).ToList();
}
public List<Resource> GetResourcesByCriteria2(string criteria2)
{
return Class1Resources.Where(r => r.Criteria2 == criteria2).ToList();
}
}
答案 0 :(得分:0)
我将您的问题解释为“我如何有效地使Class1Resources
线程安全?”所以我建议使用经典lock
,或者如果您希望写入/更改很少,则推荐ReaderWriterLockSlim
。以下是在类中使用lock
来确保线程安全性/一致性数据的方法:
public class Class1
{
// Here's your object to lock on
private readonly object _lockObject = new object();
// NOTE: made this private to control how it is exposed!
private List<Resource> Class1Resources = null;
public Class1()
{
// subscribe to external app event, with callback = ExternalAppCallback
}
private void ExternalAppCallback(List<Resource> updatedResourceList)
{
// Setting a reference is always atomic, no need to lock this
Class1Resources = new List<Resource>(updatedResourceList);
}
// Your new method to expose the list in a thread-safe manner
public List<Resource> GetResources()
{
lock (_lockObject)
{
// ToList() makes a copy of the list versus maintaining the original reference
return Class1Resources.ToList();
}
}
public List<Resource> GetResourcesByCriteria1(string criteria1)
{
lock (_lockObject)
{
return Class1Resources.Where(r => r.Criteria1 == criteria1).ToList();
}
}
public List<Resource> GetResourcesByCriteria2(string criteria2)
{
lock (_lockObject)
{
return Class1Resources.Where(r => r.Criteria2 == criteria2).ToList();
}
}
}
请注意,在此解决方案中,调用属性的getter的任何内容都不会使用锁,因此会导致线程安全问题。这就是我更改代码以使其成为私有成员的原因。