Комбинированный ConcurrentQueue и ConcurrentStack - PullRequest
0 голосов
/ 01 мая 2018

Я ищу параллельную коллекцию, к которой можно получить доступ с обеих сторон. Я хочу добиться следующего:

  • Некоторые производители добавляют товары
  • Клиент должен иметь возможность отображать последние n произведенных предметов
  • Коллекция должна содержать только элементы, произведенные в течение последних x часов

Поэтому мне нужно получить доступ к верхней части списка (FIFO) для отображения последних элементов n , но мне также нужен доступ к концу списка (LIFO), чтобы удалить элементы старше х часов непрерывно.

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Другой подход заключается в использовании класса MemoryCache, который является поточно-ориентированным и предоставляет встроенную функциональность для удаления «просроченных» элементов.

Я создал класс для хранения сохраненных значений и метки времени

public class SavedItem<T>
{
    public DateTime Timestamp { get; set; }

    public T Value { get; set; }
}

Класс коллекции будет иметь два метода: один для добавления и один для получения N-количества последних элементов

public class ExpiredCollection
{
    private readonly MemoryCache _cache;

    private readonly int _hoursLimit;

    public ExpiredCollection(int hoursLimit)
    {
        _cache = new MemoryCache("sample");
        _hoursLimit = hoursLimit;
    }

    public void Add<T>(T value)
    {
        var item = CreateCacheItem(value);
        var policy = CreateItemPolicy();

        _cache.Add(item, policy);
    }

    private CacheItem CreateCacheItem<T>(T value)
    {
        var addedValue = new SavedItem<T>
        {
            Timestamp = DateTime.Now,
            Value = value
        };
        // Create unique key to satisfy MemoryCache contract
        var uniqueKey = Guid.NewGuid().ToString();

        return new CacheItem(uniqueKey, addedValue);
    }

    private CacheItemPolicy CreateItemPolicy()
    {
        // This will set a time when item will be removed from the cache
        var expirationTime = DateTime.Now.AddHours(_hoursLimit);
        var offset = new DateTimeOffset(expirationTime);

        return new CacheItemPolicy
        {
            AbsoluteExpiration = offset
        };
    }

    public IEnumerable<T> GetLast<T>(int amount)
    {
        return _cache.Select(pair => (SavedItem<T>)pair.Value)
                     .OrderBy(item => item.Timestamp)
                     .Select(item => item.Value)
                     .Take(amount);
    }
}
0 голосов
/ 01 мая 2018

Клиент должен иметь возможность отображать последние n произведенных предметов

Дело не в удалении предметов. Я предполагаю, что вы хотите, чтобы они оставались там после того, как были показаны. Так что вам не нужна часть LIFO.

Когда количество элементов не слишком велико, вы можете использовать ConcurrentQueue и ToArray (), чтобы получить снимок (и использовать только первые n элементов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...