C# 这是ConcurrentDictionary线程安全的吗?
这是ConcurrentDictionary线程安全吗C# 这是ConcurrentDictionary线程安全的吗?,c#,C#,这是ConcurrentDictionary线程安全吗 private static ConcurrentDictionary<string, DateTime> dictionary= new ConcurrentDictionary<string, DateTime>(); public bool TextInputRecently(string text) { dictionary = new ConcurrentDicti
private static ConcurrentDictionary<string, DateTime> dictionary= new ConcurrentDictionary<string, DateTime>();
public bool TextInputRecently(string text)
{
dictionary = new ConcurrentDictionary<string, DateTime>( dictionary.Where(pair => pair.Value.Ticks >= DateTime.Now.AddMinutes(-5).Ticks)
.ToDictionary(pair => pair.Key,
pair => pair.Value));
if (dictionary.ContainsKey(text))
return true;
dictionary.TryAdd(text, DateTime.Now);
return false;
}
私有静态ConcurrentDictionary=新ConcurrentDictionary();
公共布尔文本输入最近(字符串文本)
{
dictionary=new ConcurrentDictionary(dictionary.Where(pair=>pair.Value.Ticks>=DateTime.Now.AddMinutes(-5).Ticks)
.ToDictionary(pair=>pair.Key,
pair=>pair.Value));
if(字典.容器(文本))
返回true;
TryAdd(text,DateTime.Now);
返回false;
}
我认为这不是因为字典可以重新创建,而另一个线程正在检查密钥是否存在
我是否最好在字典中循环删除过时的值?否;字典可以在
ContainsKey()
和TryAdd()
之间更改
在ConcurrentDictionary
上,不应连续调用两个方法,除非您确定不在乎它们之间是否发生变化。类似地,您不能在字典中循环,因为它可能在循环过程中发生变化 相反,您应该使用更复杂的方法(如
TryAdd()
),它将检查并添加到单个原子操作中
此外,正如您所建议的,可能会替换整个词典。否;词典可能会在
ContainsKey()
&TryAdd()
之间更改
在ConcurrentDictionary
上,不应连续调用两个方法,除非您确定不在乎它们之间是否发生变化。类似地,您不能在字典中循环,因为它可能在循环过程中发生变化 相反,您应该使用更复杂的方法(如
TryAdd()
),它将检查并添加到单个原子操作中
此外,正如您所建议的,整个词典可能会被替换。谢谢您的回答 我遵循了Scott Hannen的建议,并用MemoryCache替换了它
可能有更好的解决方案,但这适合我的需要。谢谢你的回答 我遵循了Scott Hannen的建议,并用MemoryCache替换了它
可能有更好的解决方案,但这适合我的需要。也许你要找的是缓存,比如
MemoryCache
。它是线程安全的,可以处理过期问题,因此你不必检查条目的日期或“手动”删除过期条目。可能您正在寻找的是缓存,如MemoryCache
。它是线程安全的,可以处理过期问题,因此您不必检查条目的日期或“手动”删除过期条目。
private static MemoryCache cache;
static readonly object cacheLock = new object();
private int expiry_timeout = 5;
public bool TextInputRecently(string text)
{
//Returns null if the string does not exist, prevents a race condition where the cache invalidates between the contains check and the retrieval.
var cachedString = MemoryCache.Default.Get(text, null) as string;
if (cachedString != null)
return true;
lock (cacheLock)
{
//Check to see if anyone wrote to the cache while we where waiting our turn to write the new value.
cachedString = MemoryCache.Default.Get(text, null) as string;
if (cachedString != null)
return true;
//The value still did not exist so we now write it in to the cache.
CacheItemPolicy cip = new CacheItemPolicy()
{
AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddSeconds(expiry_timeout))
};
MemoryCache.Default.Set(text, "", cip);
return false;
}
}