我有一个问题,关于如何实现列表/字典,使其在阅读时不会锁定而在写入时会锁定。 我来自GitHub项目的代码示例:TextProcessorsCache.cs
/// <summary>
/// Cache of text processors that can be re-used as they do not have
/// state
/// </summary>
public static class TextProcessorsCache
{
private static readonly ConcurrentDictionary<Type, ITextProcessor> cache;
static TextProcessorsCache()
{
cache = new ConcurrentDictionary<Type, ITextProcessor>();
}
public static ITextProcessor GetInstance<T>() where T: class, ITextProcessor, new()
{
return cache.GetOrAdd(typeof(T), new T());
}
}
我想摆脱ConcurrentDictionary<Type,ITextProcessor>
字段,而是希望任何缓存调用通过键检查值的存在,但是写入它将锁定并暂停所有读取,直到将值写入字典中< / p>
具有ReaderWriterLock的Impl。
public static class TextProcessorsCache
{
private static readonly Dictionary<Type, ITextProcessor> cache;
private static ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
static TextProcessorsCache()
{
cache = new Dictionary<Type, ITextProcessor>();
}
public static ITextProcessor GetInstance<T>() where T: class, ITextProcessor, new()
{
ITextProcessor processor;
locker.EnterReadLock();
cache.TryGetValue(typeof(T), out processor);
locker.ExitReadLock();
if (processor == null)
{
locker.EnterWriteLock();
if (cache.TryGetValue(typeof(T), out processor))
{
locker.ExitWriteLock();
return processor;
}
processor = new T();
cache[typeof(T)] = processor;
locker.ExitWriteLock();
}
return processor;
}
}
答案 0 :(得分:0)
一种可能的方法是使用泛型来确保每个实现只实例化一个实例,如下所示。 Cache
类将确保仅实例化每个T
(类型)中的一个(针对该Get
对T
的所有调用)。
您需要进行分析,以确认此实现比当前实现快/慢。
using System;
namespace Sample
{
public class Runner
{
public static void Main()
{
TextProcessorsCache.GetInstance<TextProcessor1>();
TextProcessorsCache.GetInstance<TextProcessor2>();
TextProcessorsCache.GetInstance<TextProcessor1>(); // this should not write to the console
TextProcessorsCache.GetInstance<TextProcessor2>(); // this should not write to the console
Console.ReadLine();
}
}
public static class TextProcessorsCache
{
public static ITextProcessor GetInstance<T>() where T : class, ITextProcessor, new()
{
return Cache<T>.Get();
}
}
static class Cache<T> where T : class, ITextProcessor, new()
{
internal static T value;
static Cache()
{
value = new T();
}
public static T Get()
{
return value;
}
}
public interface ITextProcessor
{
}
public class TextProcessor1 : ITextProcessor
{
public TextProcessor1()
{
Console.WriteLine("1 constructed");
}
}
public class TextProcessor2 : ITextProcessor
{
public TextProcessor2()
{
Console.WriteLine("2 constructed");
}
}
}