Thanks! I finally traced this down to one bus that I had not disposed of properly.
The documentation on subscriptions could also use some attention. Creating a Permanent/Transient subscription is described in two different places and it is wasn't clear to me that they are two unrelated ways of doing the same thing:
I went down the wrong rabbit hole fiddling with combinations of ServiceBusConfigurators and UnsubscribeTokens. Unfortunately, the "Transient" option isn't mentioned anywhere---I only discovered it by accident in IntelliSense after I realized that the Permanent() option did nothing (it's the default)---I spent a lot of time thinking that omitting it was supposed to create a transient subscription.
If it helps someone else, here's a more concise description of what I missed from the documentation:
- When terminating a subscription has been created on a pre-existing bus, you *may* continue to queue messages on the message queue by not calling the UnsubscribeToken that was generated during Subscription. If you would rather that all messages be discarded while the consumer is inactive, then you should call the UnsubscribeToken.
e.g.:
var myServiceBus = ServiceBusFactory.New(sbc =>
{
// ...
}
var unsubscribeToken = myServiceBus.Subscribe<T>();
// later:
unsubscribeToken(); // optional
myServiceBus.Dispose(); // mandatory
- When a subscription is created at the same time as the bus, you may configure the subscription to be temporary or permanent using a ServiceBusConfigurator (no UnsubscribeToken is necessary).
var myServiceBus = ServiceBusFactory.New(sbc =>
{
s => s.Consumer<MyConsumer>().Permanent(); // Message Queue keeps listening after the service bus is terminated. Permanent is the default, and therefore optional.
}
// OR
var myServiceBus = ServiceBusFactory.New(sbc =>
{
s => s.Consumer<MyConsumer>().Transient(); // Message Queue stops listening after the service bus is terminated
}
// later
myServiceBus.Dispose(): // mandatory
// No UnsubscribeToken call is necessary
- Lastly, always call the Dispose() method on the bus when you're done.
Cheers!
-Mike