And now question is why SubscriptionRegistry manages subscriptions as IdentitySet instead of OrderedCollection?
1) Performance of remove operation is the main reason. Sure, registration has a larger constant overhead than using an OrderedCollection, but it's still a theta(1) operation.Removal however, is theta(1)'ish, while with OrderedCollection, it would be theta(n/2). So for a general implementation where the usage pattern is unknown, it gives more balanced performance considering all use cases. *
2) Lessen chance of user relying on delivery order implied by registration order.
And yes, it's possible to create much better performing announcers for specific use patterns, such as a (short-lived) announcer where there's a period of registration, followed by a period of delivery, before eventual garbage collection of the announcer rather than explicit deregistration.
Personally, I think the (original) announcer pattern, where subscription collection is copied at registration, then replaced atomically, would be a better alternative.
You'd still need a mutex for the copy->add part to keep it thread-safe, but delivery would have much less overhead (no copy needed to avoid mutex guarding against mutation)
I'd be *very* wary of adding announcers that do not have thread-safe interaction between registration and delivery, though one suited for registration limited to a single thread may be a valid scenario.
Cheers,
Henry