C# te MemoryCache实例,除非需要。如果在客户端和Web应用程序中创建缓存实例,则应在应用程序生命周期的早期创建MemoryCache实例。“这是否适用于.Default?我不是说使用Dispose是错误的,老实说,我只是想澄清一下。我认为值得一提
C# te MemoryCache实例,除非需要。如果在客户端和Web应用程序中创建缓存实例,则应在应用程序生命周期的早期创建MemoryCache实例。“这是否适用于.Default?我不是说使用Dispose是错误的,老实说,我只是想澄清一下。我认为值得一提,c#,caching,memory,.net-4.0,memorycache,C#,Caching,Memory,.net 4.0,Memorycache,te MemoryCache实例,除非需要。如果在客户端和Web应用程序中创建缓存实例,则应在应用程序生命周期的早期创建MemoryCache实例。“这是否适用于.Default?我不是说使用Dispose是错误的,老实说,我只是想澄清一下。我认为值得一提的是,Dispose确实调用了附加到当前缓存项的任何CacheEntryRemovedCallback。@ElonU:下面的堆栈溢出回答解释了处理默认实例时可能遇到的一些困难:。引用:“缓存的状态设置为指示已释放缓存。任何试图调用更改缓存状态的
te MemoryCache实例,除非需要。如果在客户端和Web应用程序中创建缓存实例,则应在应用程序生命周期的早期创建MemoryCache实例。“这是否适用于.Default?我不是说使用Dispose是错误的,老实说,我只是想澄清一下。我认为值得一提的是,
Dispose
确实调用了附加到当前缓存项的任何CacheEntryRemovedCallback
。@ElonU:下面的堆栈溢出回答解释了处理默认实例时可能遇到的一些困难:。引用:“缓存的状态设置为指示已释放缓存。任何试图调用更改缓存状态的公共缓存方法(例如添加、删除或检索缓存项的方法)的尝试都可能导致意外行为。例如,如果在释放缓存后调用set方法,则会发生无操作错误。”从:检索MemoryCache实例的枚举数是一项资源密集型阻塞操作。因此,不应在生产应用程序中使用枚举数。@emberdude它与检索枚举数完全相同-您认为Select()
的实现有什么作用?我个人在单元测试[TestInitialize]函数中使用它来清除每个单元测试的内存缓存。否则,当试图比较两个函数之间的性能时,缓存会在单元测试之间持续存在,从而产生意外结果。@Jacob Morrison可以说,单元测试不是“生产应用程序”:@Mels可以说,单元测试应该按照与“生产应用程序”相同的标准编写!:)这与@Tony的回答具有相同的风险;请看我在下面的评论。@TrueWill谁是或曾经是@Tony?@AlexAngas-他可能把名字改成了magritte。请参阅,这似乎也是缺少区域功能的一个实现。非常好。我一直在尝试使用链式内存缓存监视器和guid实现一些东西,但当我试图收紧功能时,它开始变得有点难看。我不建议将此模式用于一般用途。1.它的速度很慢,实现起来没有故障,但是dispose方法非常慢。2.如果您正在从缓存中逐出过期的项,则仍然会调用更改监视器。3.当我运行性能测试时,我的机器吞噬了所有的CPU,需要很长时间才能从缓存中清除30k项。在等待了5分钟以上之后,有几次我刚刚结束了测试。@PascalMathys不幸的是,没有比这更好的解决方案了。尽管有缺点,我还是使用了它,因为它仍然是一个比使用枚举更好的解决方案。@AaronM这个解决方案还是比仅仅处理缓存并实例化一个新的好吗?对于.NET核心检查答案。您是否测试过它,看它是否更快(或更慢)?
Dim _Qry = (From n In CacheObject.AsParallel()
Select n).ToList()
For Each i In _Qry
CacheObject.Remove(i.Key)
Next
var cacheItems = cache.ToList();
foreach (KeyValuePair<String, Object> a in cacheItems)
{
cache.Remove(a.Key);
}
List<string> cacheKeys = MemoryCache.Default.Select(kvp => kvp.Key).ToList();
foreach (string cacheKey in cacheKeys)
{
MemoryCache.Default.Remove(cacheKey);
}
var cacheKeys = MemoryCache.Default.Where(kvp.Value is MyType).Select(kvp => kvp.Key).ToList();
foreach (string cacheKey in cacheKeys)
{
MemoryCache.Default.Remove(cacheKey);
}
cache.ToList().ForEach(a => cache.Remove(a.Key));
Create a new Dictionary object (let's call it AllCache)
For Each per-processor segment in the cache (one Dictionary object per processor)
{
Lock the segment/Dictionary (using lock construct)
Iterate through the segment/Dictionary and add each name/value pair one-by-one
to the AllCache Dictionary (using references to the original MemoryCacheKey
and MemoryCacheEntry objects)
}
Create and return an enumerator on the AllCache Dictionary
// By Thomas F. Abraham (http://www.tfabraham.com)
namespace CacheTest
{
using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.Caching;
public class SignaledChangeEventArgs : EventArgs
{
public string Name { get; private set; }
public SignaledChangeEventArgs(string name = null) { this.Name = name; }
}
/// <summary>
/// Cache change monitor that allows an app to fire a change notification
/// to all associated cache items.
/// </summary>
public class SignaledChangeMonitor : ChangeMonitor
{
// Shared across all SignaledChangeMonitors in the AppDomain
private static event EventHandler<SignaledChangeEventArgs> Signaled;
private string _name;
private string _uniqueId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
public override string UniqueId
{
get { return _uniqueId; }
}
public SignaledChangeMonitor(string name = null)
{
_name = name;
// Register instance with the shared event
SignaledChangeMonitor.Signaled += OnSignalRaised;
base.InitializationComplete();
}
public static void Signal(string name = null)
{
if (Signaled != null)
{
// Raise shared event to notify all subscribers
Signaled(null, new SignaledChangeEventArgs(name));
}
}
protected override void Dispose(bool disposing)
{
SignaledChangeMonitor.Signaled -= OnSignalRaised;
}
private void OnSignalRaised(object sender, SignaledChangeEventArgs e)
{
if (string.IsNullOrWhiteSpace(e.Name) || string.Compare(e.Name, _name, true) == 0)
{
Debug.WriteLine(
_uniqueId + " notifying cache of change.", "SignaledChangeMonitor");
// Cache objects are obligated to remove entry upon change notification.
base.OnChanged(null);
}
}
}
public static class CacheTester
{
public static void TestCache()
{
MemoryCache cache = MemoryCache.Default;
// Add data to cache
for (int idx = 0; idx < 50; idx++)
{
cache.Add("Key" + idx.ToString(), "Value" + idx.ToString(), GetPolicy(idx));
}
// Flush cached items associated with "NamedData" change monitors
SignaledChangeMonitor.Signal("NamedData");
// Flush all cached items
SignaledChangeMonitor.Signal();
}
private static CacheItemPolicy GetPolicy(int idx)
{
string name = (idx % 2 == 0) ? null : "NamedData";
CacheItemPolicy cip = new CacheItemPolicy();
cip.AbsoluteExpiration = System.DateTimeOffset.UtcNow.AddHours(1);
cip.ChangeMonitors.Add(new SignaledChangeMonitor(name));
return cip;
}
}
}
cache.Trim(100)
public void ClearAll()
{
var allKeys = _cache.Select(o => o.Key);
Parallel.ForEach(allKeys, key => _cache.Remove(key));
}
var field = typeof(MemoryCache).GetField("s_defaultCache",
BindingFlags.Static |
BindingFlags.NonPublic);
field.SetValue(null, null);
var cache = GlobalCachingProvider.Instance.GetAllItems();
if (dbOperation.SuccessLoadingAllCacheToDB(cache))
{
cache.Clear();
}