Stop nulling out lock object in SemaphoreSlim (#24776)
SemaphoreSlim.Dispose nulls out its lock object, and that's then used as an indication in other methods whether they should throw ObjectDisposedException. But nulling out an object used for synchronization in other methods is a bad practice, and while SemaphoreSlim.Dispose is not thread-safe to be used concurrently with other usage of the instance, it's still confusing when such usage leads to NullReferenceExceptions due to trying to lock on a null lock object. This change just changes the lock to be readonly, always set, and then whether the instance has been disposed is just a value set on that object (such that it's no larger than it used to be).