Я нашел старый код, который реализует потокобезопасную очередь.
и я попытался создать новую реализацию, используя ConcurrentQueue
Старый код
public class BoundedQueue<T> where T : class
{
private readonly Queue<T> _fixedSizeBuffer;
private object _bufferLock;
private int _limit;
public BoundedQueue(int limit)
{
_fixedSizeBuffer = new Queue<T>();
_limit = limit;
_bufferLock = new object();
for (int i = 0; i < _limit; i++)
{
_fixedSizeBuffer.Enqueue(null);
}
}
public void AddElementToBuffer(T element)
{
lock (_bufferLock)
{
_fixedSizeBuffer.Enqueue(element);
while (_fixedSizeBuffer.Count > _limit)
{
_fixedSizeBuffer.Dequeue();
}
}
}
public T GetElementAt(int index)
{
T element;
lock (_bufferLock)
{
element = _fixedSizeBuffer.ElementAt(_limit - index - 1);
}
return element;
}
}
мой новый код
public class FixedSizeConcurrentQueue<T> where T : class
{
private readonly ConcurrentQueue<T> _fixedSizeBuffer;
private int _maxSize;
public FixedSizeConcurrentQueue(int maxSize)
{
_maxSize = maxSize;
for (int i = 0; i < _maxSize; i++)
{
_fixedSizeBuffer.Enqueue(null);
}
}
public void AddElementToBuffer(T element)
{
_fixedSizeBuffer.Enqueue(element);
while (_fixedSizeBuffer.Count > _maxSize)
{
T item;
_fixedSizeBuffer.TryDequeue(out item);
}
}
public T GetElementAt(int index)
{
var element = _fixedSizeBuffer.ElementAt(_maxSize - index - 1);
return element;
}
}
Мой вопрос касается функции ElementAt()
, или мне лучше назвать ее TryGetElement()
.
в старом коде, код использовал блокировку для синхронизации различных потоков.
Однако в новом коде я удалил его, так как знаю, что использовать блокировку при параллельной коллекции - плохая практика.
Так что, если индекс не найден, потому что очередь пуста, например, я бы получил исключение.
Так я должен обернуть это попыткой catch?
объясните, пожалуйста, как бы вы это сделали.