簡體   English   中英

在自定義的ConcurrentHashSet類上使用LINQ方法嗎?

[英]Using LINQ methods on a custom ConcurrentHashSet class?

最近,我從HashSet切換到其他人發布的集合,名為“ ConcurrentHashSet”,我決定不鎖定自己的HashSet,因為我經常使用它,並且似乎更安全的選擇是使用預制的線程安全類,但我遇到了一個問題。

當我使用HashSet(默認的HashSet類)時,我正在使用FirstFirstOrDefault方法獲取HashSet值,問題是我無法再使用這些方法,而且我不確定為什么或如何重新實現它們,是FirstOrDefault甚至可能嗎? 我不確定這可能真的很簡單。

我希望有人會知道並且可以指出正確的方向。 這是我從另一個堆棧溢出答案中獲得的類,盡管我不確定這是否是原始的。

public class ConcurrentHashSet<T> : IDisposable
{
    private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
    private readonly HashSet<T> _hashSet = new HashSet<T>();

    public bool TryAdd(T item)
    {
        _lock.EnterWriteLock();

        try
        {
            return _hashSet.Add(item);
        }
        finally
        {
            if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
        }
    }

    public void Clear()
    {
        _lock.EnterWriteLock();

        try
        {
            _hashSet.Clear();
        }
        finally
        {
            if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
        }
    }

    public bool Contains(T item)
    {
        _lock.EnterReadLock();

        try
        {
            return _hashSet.Contains(item);
        }
        finally
        {
            if (_lock.IsReadLockHeld) _lock.ExitReadLock();
        }
    }

    public bool TryRemove(T item)
    {
        _lock.EnterWriteLock();

        try
        {
            return _hashSet.Remove(item);
        }
        finally
        {
            if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
        }
    }

    public int Count
    {
        get
        {
            _lock.EnterReadLock();

            try
            {
                return _hashSet.Count;
            }
            finally
            {
                if (_lock.IsReadLockHeld) _lock.ExitReadLock();
            }
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            _lock?.Dispose();
        }
    }

    ~ConcurrentHashSet()
    {
        Dispose(false);
    }
}

在內部發布的自定義類使用HashSet<T>來存儲數據。 因此,您仍然可以使用提到的方法FirstFirstOrDefault只要您以線程安全的方式進行操作即可 例如, FirstOrDefault的實現應該是這樣的:

public T TryGetFirstOrDefault()
{
    _lock.EnterReadLock();

    try
    {
        return _hashSet.FirstOrDefault();
    }
    finally
    {
        if (_lock.IsReadLockHeld) _lock.ExitReadLock();
    }
}

更新

您可以通過傳遞謂詞來概括以上內容:

public T TryGetFirstOrDefault(Func<T, bool> predicate)
{
    _lock.EnterReadLock();

    try
    {
        return _hashSet.FirstOrDefault(x=>predicate(x));
    }
    finally
    {
        if (_lock.IsReadLockHeld) _lock.ExitReadLock();
    }
}

因此,如果您有ConcurrentHashSet<Player> ,則可以將其用作例如:

var player = concurrentHashSetOfPlayers.TryGetFirstOrDefault(x=>x.Id == playerId);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM