2010-06-01 129 views
1

我有一个属性未受保护的访问成员的财产得到

public ObservableCollection<string> Name 
    { 
     get 
     { 
      return _nameCache; 
     } 
    } 

_nameCache由其他类中的方法多线程更新。更新由锁保护。问题是:我应该在我的return语句中使用相同的锁吗?不会使用锁导致竞争状态?

回答

1

这取决于你的意思是已更新

如果您的意思是修改了参考文献,即_nameCache = newvalue;,那么正如马克所说的,是的,您应该(使用相同的锁)和不,您不会得到竞争条件。

但是,如果您的意思是将项目添加到_nameCache所引用的实例中并将其移除,那么您将不需要锁定返回值(因为参考本身不会更改)。但是,在获取它之后,您必须小心如何阅读集合 - 理想情况下,您应该在调用其任何方法之前使用同一个锁。

要么是这样,要么您可以使用事件模型来通知新项目等,如果您只需要跟踪更改 - 因为事件将在当前锁定集合的线程上引发。

如果这不适合(因为您总是通过索引器或其他方式获取元素),那么您始终可以通过此属性返回ObservableCollection的副本 - 即return new ObservableCollection<string>(_nameCache);。这将使属性的返回值短暂存在,但让所有调用者可以自由地枚举和索引,而不用担心来自其他线程的状态损坏。

1

是的,你应该。如果您不添加锁,那么可能不会返回最新的_nameCache值。

public ObservableCollection<string> Name 
{ 
    get 
    { 
     lock (_yourLockObject) 
     { 
      return _nameCache; 
     } 
    } 
} 
0

是的,你可以使用同一个锁对象。我假设你有一个变量被声明为如下的锁:private object _lock = new object();如果是这样,你可以像下面的代码块一样使用_lock对象。

public ObservableCollection<string> Name 
{ 
    get 
    { 
     lock(_lock) 
     { 
      return _nameCache; 
     } 
    } 
} 

如果您没有实现在多个线程apptempting访问_nameCache您可能会收到这不是当前呼叫此属性格式的范围内的值的情况下锁定。因此,如果多线程正在访问相同类的成员,例如上面列出的Propery,则它必须实施同步(锁)。

享受!