First of all, safety and flow rate are important here. A delegate update is not atomic; it requires updating 6 fields and a list. To make it atomic so that it cannot be damaged requires blocking, which is too expensive for such a basic operation, which rarely needs to be thread safe.
By making it immutable, the delegate object cannot be damaged, since it always sets the fields for an object that is not yet referenced. Reassigning a reference to a delegate object is an atomic, basic guarantee of the .NET memory model. So there’s no need for a lock anymore. Compromise is a less efficient use of memory, this is a small penalty.
Keep in mind that streaming delegate updates does not automatically make your code thread safe. The verification and security code must copy the link to avoid NRE, and you can call back to a method that has already been unsubscribed.
source share