用于基于时间的查找的带时间戳,线程安全的数据结构?

时间:2014-05-02 08:26:57

标签: c# data-structures concurrency thread-safety timestamp

我想实现一个可附加到的列表类型数据结构,带有相关的时间戳。关键是我可以获得比特定时间戳更新的所有数据。

我尝试过使用ConcurrantDicitionary,但我不相信这是最好的方法。我更希望有一个List<十进制[2]>对于我不会进入这里的应用程序。数组的第一个值可以包含时间戳,第二个值可以是值。或者,可以使用List< TimeStampedObject>。但是,apparently在C#中没有并发列表。

对于记录,我的数据是按时间戳排序的。

我希望能够做到这样的事情:

public static Dictionary<DateTime, decimal> GetLatest(DateTime since, Dictionary<DateTime, decimal> requestedDict)
{
    Dictionary<DateTime, decimal> returnList = new Dictionary<DateTime, decimal>();
    returnList = requestedDict.Where(x => x.Key > since).ToDictionary(x => x.Key, x => x.Value);
    return returnList;
}
  • 更新:

这是我提出的List项目;如果这有任何可能的挫折,请告诉我:

public class ConcurrentList: List<StampedValue>
    {

        ReaderWriterLockSlim _samplesLock = new ReaderWriterLockSlim();

        public ConcurrentList() : base()
        {
        }

        public void AddThreadSafe(StampedValue item){

            this._samplesLock.EnterWriteLock();
            try
            {
                this.Add(item);

            }
            finally
            {
                this._samplesLock.ExitWriteLock();
            }

        }

        public List<StampedValue> GetLatest(long since){
            return this.Where( s => s.Timestamp > since ).ToList();
        }

        public List<StampedValue> GetLatest(DateTime since){
            throw new NotImplementedException();
        }
    }


    public class StampedValue
    {
        public long Timestamp { get; set; }
        public decimal Value { get; set; }

        public StampedValue(long t, decimal v){
            this.Timestamp = t;
            this.Value = v;
        }

    }

2 个答案:

答案 0 :(得分:4)

在我看来,您最好的选择就是使用List<T>保护ReaderWriterLockSlim。例如:

class Sample
{
    public DateTime EventTime { get; set; }
    public decimal Value { get; set; }
}

List<Sample> _samples = new List<Sample>();

ReaderWriterLockSlim _samplesLock = new ReaderWriterLockSlim();

// to get items after a particular date
List<Sample> GetSamplesAfterDate(DateTime dt)
{
    _samplesLock.EnterReadLock();
    try
    {
        return _samples.Where(s => s.EventTime >= dt).ToList();
    }
    finally
    {
        _samplesLock.ExitReadLock();
    }
}

如果已知您的列表按时间顺序排列,那么您可以通过在列表上使用二进制搜索来查找大于或等于传递时间戳的第一个项目来提高性能。我刚刚在这里使用了LINQ版本,因为重点是说明锁定。

附加到列表类似:获取写锁定,追加并释放锁定:

void AppendSample(Sample s)
{
    _samplesLock.EnterWriteLock();
    try
    {
        _samples.Add(s);
    }
    finally
    {
        _samplesLock.ExitWriteLock();
    }
}

另一种方法是使用List<KeyValuePair<DateTime, decimal>>而不是List<Sample>。锁定将保持不变。

在大多数情况下,这应该表现得很好。

答案 1 :(得分:0)

您是否看过SynchronizedCollection&lt; T&gt;类?在我看来,你正在寻找。您还可以专门化SynchronizedKeyedCollection&lt; K,T&gt;

EDIT(2014 / May / 8):

我上面链接的文档并不像人们想的那样清晰或有用,因此查看reference implementation可能会有所帮助。

相关问题