c#锁定对象共享的公共方法和事件回调代码
本文关键字:方法 事件 回调 代码 锁定 对象 共享 | 更新日期: 2023-09-27 18:10:14
关于锁的问题,文本指的是下面的示例代码…我有一个类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();
}
}
我将您的问题解释为"如何有效地使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的东西都不会使用锁,因此会导致线程安全问题。这就是为什么我更改代码使其成为私有成员。