diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs index 092815ff6e..b403b37068 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs @@ -1,6 +1,7 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; +using Nito.AsyncEx; using Volo.Abp.DependencyInjection; using Volo.Abp.VirtualFileSystem; @@ -9,50 +10,33 @@ namespace Volo.Abp.TextTemplating.VirtualFiles public class LocalizedTemplateContentReaderFactory : ILocalizedTemplateContentReaderFactory, ISingletonDependency { private readonly IVirtualFileProvider _virtualFileProvider; - private readonly Dictionary _readerCache; - private readonly ReaderWriterLockSlim _lock; + private readonly ConcurrentDictionary _readerCache; + protected SemaphoreSlim SyncObj; public LocalizedTemplateContentReaderFactory(IVirtualFileProvider virtualFileProvider) { _virtualFileProvider = virtualFileProvider; - _readerCache = new Dictionary(); - _lock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); + _readerCache = new ConcurrentDictionary(); + SyncObj = new SemaphoreSlim(1, 1); } public async Task CreateAsync(TemplateDefinition templateDefinition) { - _lock.EnterUpgradeableReadLock(); + if (_readerCache.TryGetValue(templateDefinition.Name, out var reader)) + { + return reader; + } - try + using (await SyncObj.LockAsync()) { - var reader = _readerCache.GetOrDefault(templateDefinition.Name); - if (reader != null) + if (_readerCache.TryGetValue(templateDefinition.Name, out reader)) { return reader; } - _lock.EnterWriteLock(); - - try - { - reader = await CreateInternalAsync(templateDefinition); - _readerCache[templateDefinition.Name] = reader; - return reader; - } - finally - { - if (_lock.IsWriteLockHeld) - { - _lock.ExitWriteLock(); - } - } - } - finally - { - if (_lock.IsUpgradeableReadLockHeld) - { - _lock.ExitUpgradeableReadLock(); - } + reader = await CreateInternalAsync(templateDefinition); + _readerCache[templateDefinition.Name] = reader; + return reader; } }