gpt4 book ai didi

c# - Microsoft Enterprise Library 缓存应用程序 block 不是线程安全的?

转载 作者:太空狗 更新时间:2023-10-29 23:56:21 26 4
gpt4 key购买 nike

我创建了一个 super 简单的控制台应用程序来测试企业库缓存应用程序 block ,其行为令人费解。我希望我在设置中搞砸了一些容易修复的东西。出于测试目的,我让每个项目在 5 秒后过期。

基本设置——“每秒选择一个 0 到 2 之间的数字。如果缓存中没有它,就把它放在那里——否则就从缓存中获取它。在 LOCK 语句中执行此操作以确保线程安全。

应用程序配置:

<configuration>
<configSections>
<section name="cachingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<cachingConfiguration defaultCacheManager="Cache Manager">
<cacheManagers>
<add expirationPollFrequencyInSeconds="1" maximumElementsInCacheBeforeScavenging="1000"
numberToRemoveWhenScavenging="10" backingStoreName="Null Storage"
type="Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Cache Manager" />
</cacheManagers>
<backingStores>
<add encryptionProviderName="" type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Null Storage" />
</backingStores>
</cachingConfiguration>
</configuration>

C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Common;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;

namespace ConsoleApplication1
{
class Program
{
public static ICacheManager cache = CacheFactory.GetCacheManager("Cache Manager");
static void Main(string[] args)
{
while (true)
{
System.Threading.Thread.Sleep(1000); // sleep for one second.
var key = new Random().Next(3).ToString();
string value;
lock (cache)
{
if (!cache.Contains(key))
{
cache.Add(key, key, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromSeconds(5)));
}
value = (string)cache.GetData(key);
}
Console.WriteLine("{0} --> '{1}'", key, value);
//if (null == value) throw new Exception();
}
}
}
}

输出——如何防止缓存返回空值?

2 --> '2'
1 --> '1'
2 --> '2'
0 --> '0'
2 --> '2'
0 --> '0'
1 --> ''
0 --> '0'
1 --> '1'
2 --> ''
0 --> '0'
2 --> '2'
0 --> '0'
1 --> ''
2 --> '2'
1 --> '1'
Press any key to continue . . .

最佳答案

您看到的是您的 CacheItem 由于 5 秒 SlidingTime 过期而过期。

在返回缓存值之前,GetData 方法执行检查以查看 CacheItem 是否已过期。如果它已过期,则从缓存中删除 CacheItem 并返回 null。但是,对 Contains 的调用将返回 true,因为 CacheItem 在缓存中,即使它可能已经过期。这似乎是设计使然。考虑到这一点,明智的做法是不要缓存 null 值以表示没有数据,因为您无法从实际缓存的 null 值中辨别过期的 CacheItem。

假设您不缓存空值,那么 Luke 的解决方案应该适合您:

value = cache.GetData(key) as string;

// If null was returned then it means that there was no item in the cache
// or that there was an item in the cache but it had expired
// (and was removed from the cache)
if (value == null)
{
value = key;
cache.Add(key, value, CacheItemPriority.Normal, null,
new SlidingTime(TimeSpan.FromSeconds(5)));
}


参见 The Definitive Guide To Microsoft Enterprise Library获取更多信息。

关于c# - Microsoft Enterprise Library 缓存应用程序 block 不是线程安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1302643/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com