I've adapted the code from the latest Rx sources. Concurrency-related gate objects where present in the JoinObserver1 to protect a list of ActivePlan0 instances. The second place was in the when() to again build a list of ActivePlan0 instances. Since the Rx.NET source didn't contain any other locks, volatiles or concurrent instances, I assumed they are safe.