下面的代码是线程安全的吗?
我每隔service
就需要调用一个async
方法,因此我cannot将foreach
循环置于锁定之下.
但是,将锁下从_dictionary
到ImmutableList
的所有值复制到锁下,退出锁,然后像往常一样迭代它们并调用async
方法,这是否是线程安全的?
public class Cache
{
private readonly ReaderWriterLockSlim lockObject = new();
private readonly IDictionary<string, Service> _dictionary = new Dictionary<string, Service>();
public Service GetOrAdd(string key)
{
lockObject.EnterUpgradeableReadLock();
try
{
if (_dictionary.TryGetValue(key, out var service))
{
return service;
}
lockObject.EnterWriteLock();
try
{
var value = new Service();
_dictionary.Add(key, value);
return service;
}
finally
{
lockObject.ExitWriteLock();
}
}
finally
{
lockObject.ExitUpgradeableReadLock();
}
}
public async Task CallServices()
{
var services = GetServices();
foreach (var service in services)
{
await service.DoStuffAsync();
}
}
private ImmutableList<Service> GetServices()
{
lockObject.EnterReadLock();
try
{
return _dictionary.Values.ToImmutableList();
}
finally
{
lockObject.ExitReadLock();
}
}
}
用ConcurrentDictionary
替换Dictionary
并从GetServices
移除锁是一种 Select ,但我仍然必须将锁保留在GetOrAdd
中,因为实际上我有2个集合要维护,而不仅仅是_dictionary
.我想知道是否有可能用普通的Dictionary
美元.