After profiling, I've discovered that a specific object in my application will benefit greatly by using an object pool instead of constructing it. This application is based around producer/consumer queues with multiple threads.
The ConcurrentBag collection is basically an ObjectPool, and seems perfect as the backing store for the application's Object Pool. If I understand correctly, the ConcurrentBag conceptually works like this:
The problem is I already know that the application will always request the object on thread 'A', and always return it on thread 'B'. Thus, it will always default to the steal case.
Knowing this access pattern, would it be better to back the object pool with a different collection provided by the framework?
For your use case a ConcurrentQueue would be the better structure to use. As you surmised ConcurrentBag should only really be used when you are primarily inserting and pulling from the same thread, ConcurrentQueue does not have thread affinities.
Most Producer Consumer models will have separate threads writing and reading, that is why BlockingCollection<T>
uses a ConcurrentQueue<T>
as its default backing store.