Search code examples
c#.netmultithreadinglockingreaderwriterlockslim

Why does ReaderWriterLockSlim call Sleep() inside of EnterReadLock()?


I'm trying to implementing a threadsafe resource pool that is fast to access and only gets occasional updates. For that I use the ReaderWriterLockSlim with an extension method to enter and exit the read lock. While profiling the thread utilization was unexpectedly very low.

I verified that no write happened to the pool, so EnterWriteLock() was never called.

internal Mesh GetMesh(string name)
{
    using (CacheLock.Read())
    {
        if (MeshDictionary.TryGetValue(name, out var m))
        {
            return m;
        }
    }
    // <snip>
}
public static ReadLock Read(this ReaderWriterLockSlim l)
{
    return new ReadLock(l);
}
internal class ReadLock : IDisposable
{
    private readonly ReaderWriterLockSlim _lockObject;
    public ReadLock(ReaderWriterLockSlim l)
    {
        _lockObject = l;
        l.EnterReadLock();
    }
    public void Dispose()
    {
        _lockObject.ExitReadLock();
    }
}

While profiling I found that most threads spend about 25% of their time inside of EnterReadLock(). The internal sleep of that function takes about 19% and the rest is time used for spinning actively and other overhead. I would expect the EnterReadLock not to sleep at all and only spin for a short time. Is there a way to get better utilization and reduce wait time?


Solution

  • The Slim versions of the threading components use spinlocks, which are fast but CPU intensive. If you are expecting a wait of any duration then use the older ReaderWriterLock.