I have situation, where I have to receive requests in a Web API method, queue those request and then send the bulk to a database (Solr instance).
I am not really su
public class ThresholdBuffer
{
private ConcurrentBag _buffer;
private int _threshold;
public ThresholdBuffer(int threshold)
{
_threshold = threshold;
_buffer = new ConcurrentBag();
}
public void Add(T item)
{
_buffer.Add(item);
if(_buffer.Count >= _threshold)
{
Recycle();
}
}
public void Recycle()
{
var value = Interlocked.Exchange>(ref _buffer, new ConcurrentBag());
//flush value
}
}
You may add locking logic in Recycle to prevent multiple ConcurrentBag creation and flushing nearly empty bag. But my opinion is this is less evil than lock.
Update. Lock free without aditional ConcurrentBag creation
public class ThresholdBuffer
{
private ConcurrentBag _buffer;
private int _copacity;
private int _threshold;
public ThresholdBuffer(int threshold)
{
_threshold = threshold;
_copacity = 0;
_buffer = new ConcurrentBag();
}
public void Add(T item)
{
_buffer.Add(item);
if (Interlocked.Increment(ref _copacity) == _threshold)
{
Recycle();
}
}
public void Recycle()
{
var value4flasshing = Interlocked.Exchange>(ref _buffer, new ConcurrentBag());
Thread.VolatileWrite(ref _copacity, 0);
}
}
ps You may use any ConcurrentCollection instead of ConcurrentBag