How do you prevent adding duplicate values in a static ObservableCollection thread safe?
I'm not sure what to do as far as managing the _namePrefixes for this control. I know I can make it non-static, but it makes sense to be static to be consistent across all uses of this control in terms of content for my project. Also, I chose ObservableCollection because of the following scenario:
I have 2 client machines, one for standard use, the other for managing options (admin) such as a Name Prefix list. If the client is running and the admin makes a change, the client should update itself and reflect those changes after it has already been loaded. Oh, and because this is a WPF item and I wanna databind it to a ListBox. If neither of these make me use an ObserableCollection, no big deal... I'll use something like a List, but I don't think that'll change the original question.
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; 开发者_Python百科}
#endregion
}
}
If what you're looking to do is avoid adding the same actual instance to the collection multiple times because of threaded operations overlapping, then the standard solution for this is to do the work inside of a lock
block.
public static void AddNamePrefix(NamePrefix prefix)
{
lock(_namePrefixes)
{
if(!_namePrefixes.Contains(prefix)) _namePrefixes.Add(prefix);
}
}
(and the same for suffixes)
Locks are single-use resources, so when a thread has a lock on an object (in this case, the collection), then any other thread attempting to acquire the lock will be blocked until the existing lock is released. The upshot in this scenario is that only one thread will be able to execute the code inside the lock block at any given time; all others will wait until the current thread finishes, then proceed on one by one.
It's worth noting that the object used to lock does not have to have anything to do with the operations taking place inside of the block. As long as the locks attempt to lock on the same object, then this will work. It's a common practice to declare a dedicated instance of type object
to lock on, but in this case the collection can serve that purpose.
精彩评论