Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making IDistributedCache thread-safe in .Net Core 3.1

I need to use IDistributedCache in my app and it could be MemoryDistributedCache or RedisCache as an underlying implementation. My understanding those are not thread-safe, so I created my own wrapper with usage of ReaderWriterLockSlim.

ReaderWriterLockSlim allows multiple threads for reading or exclusive access for writing. And now I wonder if it's the right tool for the job and if MemoryDistributedCache and RedisCache reading methods are thread-safe.

As to overall solution - I understand it takes time to store and read values from a distributed cache like Redis. But I don't have much choice as the values I store are even slower to get and manage.

Here's the snippet:

...
        public async Task<byte[]> GetAsync(string key, CancellationToken token = new CancellationToken())
        {
            _cacheLock.EnterReadLock();
            try
            {
                return await _cache.GetAsync(GetCacheKey(key), token);
            }
            finally
            {
                _cacheLock.ExitReadLock();
            }
        }

        public async Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = new CancellationToken())
        {
            _cacheLock.EnterWriteLock();
            try
            {
                await _cache.SetAsync(GetCacheKey(key), value, options, token);
            }
            finally
            {
                _cacheLock.ExitWriteLock();
            }
        }

        public async Task RemoveAsync(string key, CancellationToken token = new CancellationToken())
        {
            _cacheLock.EnterWriteLock();
            try
            {
                await _cache.RemoveAsync(GetCacheKey(key), token);
            }
            finally
            {
                _cacheLock.ExitWriteLock();
            }
        }
like image 449
alvipeo Avatar asked Mar 21 '20 19:03

alvipeo


1 Answers

All IDistributedCache implementations should be thread-safe. If one is not, then please create a bug report to get it fixed.

Even if one of them is not thread-safe, using ReaderWriterLockSlim to guard async code is invalid. From the docs:

ReaderWriterLockSlim has managed thread affinity; that is, each Thread object must make its own method calls to enter and exit lock modes. No thread can change the mode of another thread.

The simplest workaround would be to use SemaphoreSlim instead of ReaderWriterLockSlim.

like image 80
Stephen Cleary Avatar answered Oct 05 '22 06:10

Stephen Cleary