Clearing .NET Cache for Sitecore - c#

I need to clear a Cache which is being used for a custom module in Sitecore, what's the best practice to clear it?
We're currently adding keys to the cache with
System.Web.HttpContext.Current.Cache.Add(key, obj, dependencyKey, DatTime.MaxValue);
This cache does not get cleared out on publish though and I need to clear it manually. I know it is possible to hook into Sitecores publish event, but need a way to clear it.
Tried removing keys with:
System.Web.HttpContext.Current.Cache.Remove(key);
But it did not do the trick

There is no .Clear() method.
You can iterate over all the entries and remove them by their key (or ID), using the GetEnumerator method of the Cache class.
IDictionaryEnumerator enumerator = Cache.GetEnumerator();
while(enumerator.MoveNext())
{
Cache.Remove(enumerator.Key);
}
I would run this code in a publish:end:remote event.

Related

Remove all items from MemoryCache

I would love to remove all items from MemoryCache.
What I have tried already:
var listDBCalls = ((FixedSizedQueue<DalCacheDto>)MemoryCache.Default.Get($"DAL_CACHE_{HttpContext.Current?.User?.Identity?.Name}"))?.ToList();
listDBCalls.clear();
If I watch this code in debugger, it shows that listDBCalls is really empty. But, calling again:
((FixedSizedQueue<DalCacheDto>)MemoryCache.Default.Get($"DAL_CACHE_{HttpContext.Current?.User?.Identity?.Name}"))?.ToList()
is showing me that all items are still there. Why is that?
Avoid to use the default memory cache to have more control.
Create your own memory cache (by example as a static property of a static class) and when you need to erased it you can simply create a new one to replace the older one. Don't forget to call the dispose method.
It seems the way to go : How to clear MemoryCache?
Edit
When I read you code I'm not sure what you want to do.
If you want to remove a particular entry (which seems the case) you can use the remove method.
MemoryCache.Default.Remove($"DAL_CACHE_{HttpContext.Current?.User?.Identity?.Name}")

StackExchange.Redis pipelining on for-loop?

Preface
I have a simple interface that assumes dependencies between keys.
Two of its methods are:
Remove(string key) - that removes a single key from the cache.
RemoveDependentsOf(string baseKey) - that removes baseKey and all dependents of baseKey.
The dependents of baseKey are specified in a Redis set.
So in order to remove all dependents of baseKey I have to read the baseKey's set and then loop them to delete each of them.
Question
I read StackExchange.Redis documentation so I know about their legendary pipelining suppport, and according to their documentation the following code should work very efficient.
However, I cannot seem to understand how could the library pipeline the KeyDelete commands as the method returns a boolean value whether the key was deleted or not.
So before executing the second KeyDelete command, the first one should have been sent and received its response (that's not efficient).
What am I missing here?
How should have I written the below code?
public void Remove(string key)
{
_redis.KeyDelete(key);
}
public void RemoveDependentsOf(string key)
{
Remove(key);
var setKey = GetDependencySetKey(key);
RedisValue[] dependents = _redis.SetMembers(setKey);
foreach (var dependentKey in dependents)
{
RemoveDependentsOf(dependentKey);
}
// This is the way to remove the whole set
_redis.KeyExpire(setKey, TimeSpan.Zero);
}
You’re using synchronous methods and, although you don’t explicitly depend on the result of the KeyDelete operation, StackExchange.Redis doesn’t know that you’re not using the result. You are therefore not getting any of the pipelining benefits offered by the library.
The documentation explicitly calls out the two ways that you can use the pipelining support; use the Async method and perform a Task.WhenAll if you want to know when it’s done or use Fire and Forget. You can explicitly tell the library that you want to do this by passing CommandFlags.FireAndForget to your commands, e.g.
_redis.KeyDelete(key, CommandFlags.FireAndForget)
Note this will cause a default result to be returned from the call rather than the actual result. Given that you are disregarding those results anyway you should be OK!

Concurrency of modifying a Roslyn workspace? How does Visual studio do it?

probably a stupid question, but: Is there any way to reliable apply changes to a Roslyn workspace concurrently? And if not, what is the best practice to ensure it's done in correct order?
Example: Say you have some solution loaded into a Workspace, and have a basic function that will add a new project to the solution:
private Workspace _workspace;
// This is not thread-safe, right?
void AddProject()
{
var project = _workspace.CurrentSolution.AddProject(/* ... */);
_workspace.TryApplyChanges(project.Solution);
}
First question: Correct me if wrong, but I think AddProject would not be thread-safe, is that correct?
For example, lets say you want to add to new projects concurrently. So you call AddProject() twice concurrently.
My understanding is there is a race condition, and you might end up with both projects added (if one of the calls completes TryApplyChanges before the other call reaches _workspace.CurrentSolution), or only one of the projects added (if both calls have reached _worksapce.CurrentSolution before either has executed TryApplyChanges).
Second question: If my understanding is correct, then is there any best way to avoid these concurrency issues? I suppose the only real way would be to schedule/execute each modification sequentually, right?
How does Visual Studio, for example, do this.. Are modifications to the Workspace e.g. only done on the Dispatcher?
Thanks
The underlying code is thread-safe, but your usage is not.
TryApplyChanges() will return false if the solution changed in the meantime. If that happens, you need to try the changes again (starting from the new CurrentSolution).
Basically, you need to write
Solution changed;
do {
changed = _workspace.CurrentSolution....();
} while (!_workspace.TryApplyChanges(changed);
This is called a compare-and-swap loop; see my blog for more details.

Azure Cache - How to Determine if a Key is in cache?

Is there a way, using Azure Caching, to determine if an object having a specific key exists in cache, without actually returning the object itself?
I'm currently doing something like
public bool IsKeyInCache(string cacheKey)
{
DataCacheItem item = null;
CacheRetryPolicy.ExecuteAction(() =>
{
item = cache.GetCacheItem(cacheKey);
});
return item != null;
}
But, because the object in cache is very large and expensive to deserialize, performance is horrible.
I've dug through the MSDN documentation and don't see any alternative, but maybe I'm missing something.
My best idea so far is to add a small "marker" object to cache at the same time as my large object and check for existence of the "marker" object where deserialization is inexpensive. But this isn't a robust solution, as it's entirely possible for my large object to get purged from cache while the "marker" object remains.
I believe the API you're looking for is DataCache.Get(key):
windows azure caching - best practice for checking whether a key exist or not
http://msdn.microsoft.com/en-us/library/ff424908%28v=azure.10%29.aspx
But I still think you're best bet is to NOT "micro-manage" the cache, just query, and let Azure decide.
IMHO...

Least cpu intensive method of checking if a list has changed in c#

I have a function that is to be called if a list has changed since it was last called, what would be the best way of implementing this?
ex:
List<A> OurList = new List<A>();
private void Update()
{
Boolean Changed = //?
if(Changed) CheckList(OurList);
}
I would have assumed make a variable to store the old list and compare, but how would I update the old list to the new list without copying it all out? (If I do an assign, it will update the "old list" too)
Use an ObservableCollection<T> instead of a List, then subscribe to the CollectionChanged event.
This way, you will be told when the list is changed instead of having to scan the data to figure out what happened after the fact.
The most efficient way would be to wrap the List<> in your own class and have all the mutating methods (Add, Remove) set a boolean flag.
Your Method can then just look at that flag and reset it.
If you're using .NET 4.0, you could use the ObservableCollection class. (prior to 4.0, you would need to reference WPF).
Once you create your list, just add a handler to the CollectionChanged event.
Your best bet would be to use an ObservableCollection<T> or BindingList<T> to get push notification of a change. You could also subclass Collection<T> if you want any custom behaviour.
To answer your question as asked (except for the cpu-intensive bit), you can use an existing feature of List<T>: it maintains its own version internally so that it can throw if the collection has changed during enumeration.
This is based on analyzing code from reflector. It is not part of any contract, so it is liable to break at any time. It may also not work in a partial-trust environment. Please use with care:
public static int GetVersion<T>(this List<T> list)
{
return (int)list.GetType()
.GetField("_version", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(list);
}
...
private int _lastCheckedVersion = 0;
private void Update()
{
int currentVersion = ourList.GetVersion();
if(currentVersion != _lastCheckedVersion) CheckList(ourList);
_lastCheckedVersion = currentVersion;
}
Restrict access to the list.
Allow changes only through a prescribed API.
In that API, set a flag whenever the ChangeList method is called.
Are you trying to see if the List itself changed (adding/removing items), or if an item on the list changed.
If you're simply looking to see if a list had an item added/removed, the easiest would be to wrap the List in a new class and override the Add/Remove methods for your object to trigger a boolean.
The more complicated requirement is if you need to know if an item contained on the list has changed (a property or field in the class object that is referenced in the list). If that's the case, it depends on your specific situation. You could put in the setter for the properties for those classes a way to trigger a boolean that would do the same thing as before. But this depends on the complexity of the class in the generic list.

Categories

Resources