2010-06-25 119 views
0

我不知道该怎么尽可能管理_namePrefixes此控件做。我知道我可以使它成为非静态的,但在我的项目的内容方面,在这个控件的所有用途上保持一致是很有意义的。此外,我选择的ObservableCollection因以下情形的:如何防止在静态ObservableCollection线程安全中添加重复值?

我有2个客户机,一个用于标准用途,其他用于管理选项(管理员),如名称前缀列表。如果客户端正在运行并且管理员进行了更改,则客户端应该自行更新并在已加载后反映这些更改。哦,因为这是一个WPF项目,我想将它绑定到ListBox。如果这些都不会让我使用ObserableCollection,那么没什么大不了的......我会使用类似List的东西,但我认为这不会改变原来的问题。

using System; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Media; 

namespace MyProject 
{ 

    public class NameField : TextBox 
    { 
     private static ObservableCollection<NamePrefix> _namePrefixes; 
     private static ObservableCollection<NameSuffix> _nameSuffixes; 

     static NameField() 
     { 
      _namePrefixes = new ObservableCollection<NamePrefix>(); 
      _nameSuffixes = new ObservableCollection<NameSuffix>(); 
     } 

     public static void AddNamePrefix(Int32 id, String prefix) 
     { 
      //TODO: WHAT DO I DO HERE!? 
     } 

    } 

    /// <summary> 
    /// A Key/Value structure containing a Name Prefix ID and String value. 
    /// </summary> 
    public struct NamePrefix 
    { 
     #region Constructor 

     public NamePrefix(Int32 id, String prefix) 
      : this() 
     { 
      ID = id; 
      Prefix = prefix; 
     } 

     #endregion 

     #region Properties (ID, Prefix) 

     public Int32 ID { get; set; } 
     public String Prefix { get; set; } 

     #endregion 
    } 

    /// <summary> 
    /// A Key/Value structure containing a Name Suffix ID and String value. 
    /// </summary> 
    public struct NameSuffix 
    { 
     #region Constructor 

     public NameSuffix(Int32 id, String suffix) 
      : this() 
     { 
      ID = id; 
      Suffix = suffix; 
     } 

     #endregion 

     #region Properties (ID, Prefix) 

     public Int32 ID { get; set; } 
     public String Suffix { get; set; } 

     #endregion 
    } 
} 
+0

请不要无意义的内容(如空白区域陈述或者,说实话,'#region'在所有语句)在发布代码。 – 2010-06-25 18:48:11

+0

是什么问题? – 2010-06-25 19:32:20

回答

2

如果你希望做的是避免增加相同的实际实例的集合,因为线程操作的多次重叠的,那么这个标准的解决方案是做一个lock块内的工作。

public static void AddNamePrefix(NamePrefix prefix) 
{ 
    lock(_namePrefixes) 
    { 
     if(!_namePrefixes.Contains(prefix)) _namePrefixes.Add(prefix); 
    } 
} 

(与同为后缀)

锁是单次使用的资源,因此,当一个线程拥有一个对象上的锁(在这种情况下,集合),则任何其他线程尝试获得锁将被阻止,直到现有的锁被释放。这种情况下的结果是,在任何给定的时间只有一个线程能够执行锁块内的代码;所有其他人将等待直到当前线程结束,然后逐一进行。

值得一提的是用来锁定对象不必有什么用行动作出了块内的地方。只要锁试图锁定相同的对象,那么这将工作。这是一个常见的做法是申报object类型的专用实例来锁定,但在这种情况下,集合可以达到这一目的。

+0

访问该锁中的代码的2个请求是否有可能以某种方式在该锁内部发生?基本上这两个线程可能同时发生,它们同时激活锁定(),并且都意外进入? – 2010-06-25 19:21:33

+0

@myermian:不,这就是锁的全部。 – 2010-06-25 19:32:52