Edit (2016-1-26): Channels are NOT thread safe. The documentation on that has changed between April and May 2015. The new text:
Channel instances must not be shared between threads. Applications should prefer using a Channel per thread instead of sharing the same Channel across multiple threads. While some operations on channels are safe to invoke concurrently, some are not and will result in incorrect frame interleaving on the wire. Sharing channels between threads will also interfere with * Publisher Confirms.
From your question it sounds like you don't have a predefined, fixed number of threads that do mostly publishing / subscribing to RabbitMQ (in which case you might consider creating a channel as part of the initialization of the thread, or using a ThreadLocal<IModel>
).
If concurrent RabbitMQ operations are rare or message sizes always small, you might get away with simply putting a lock(channel)
around all your RabbitMQ pub/sub operations. If you need multiple requests to be transmitted in an interleaved fashion - that's what channels are for in the first place - using arbitrary threads, you might want to create a channel pool, e.g. a ConcurrentQueue<IModel>
where you Enqueue unused channels and Dequeue for the time you need them. Channel creation is very low-overhead, and I have the feeling, from performance tests, that the process of channel creation does not involve any network io, i.e. it seems a channel gets automatically created in the RabbitMQ server on first use by a client. Edit: Thanks Pang, There is no need to open a channel per operation and doing so would be very inefficient, since opening a channel is a network roundtrip.
OLD (pre 2016-1-26): The now mostly obsolete details of the Java and .net implementations:
Re: channels and multiple threads, which is a bit confusing due to its dependence on the implementation.
Java implementation: Channels are thread safe:
Channel instances are safe for use by multiple threads.
But:
confirms are not handled properly when a Channel is shared between multiple threads
.net implementation: Channels are not thread safe:
If more than one thread needs to access a particular IModel instances, the application should enforce mutual exclusion itself.
Symptoms of incorrect serialisation of IModel operations include, but are not limited to,
• invalid frame sequences being sent on the wire
• NotSupportedExceptions being thrown ...
So in addition to Robin's useful answer, which applies regardless of whether it's thread safe or not, in the .net implementation, you can't just share a channel.