Caching with UnitOfWork - c#

at the moment my program is constantly querying the same repositories repeatedly. I'm currently using UnitOfWork pattern to query my tables.
For example a query that is ran very often
var peopleCollection = UnitOfWork.PersonRepository.Get(x => x.Active);
To enhance my software to reduce repetitive task, may I ask what's the proper approach I should be taking to cache if I have a UnitOfWork pattern. I understand I can save the collection to a dictionary and call that dictionary whenever I want to use it. But the main issue with that approach is that I would have an outdated collection of people if another user were to save a new person.

The short answer is that each situation requires a slightly different solution.
In general, the best solution is to use Decorator pattern to cache duplicate data calls, and ensure that the cache invalidates old data with an appropriate expiration policy.
For example, suppose that it won't bother your users to have Person data that is up to 60 seconds old. In that case, you could set the cache expiration during to 60 seconds.
Here is a sample for a generic cached item, which would be perfect for storing in a dictionary:
public class CachedItem<T>
{
private readonly T _item;
private readonly DateTime _expirationTime;
public CachedItem(T obj, TimeSpan cacheDuration)
{
_item = obj;
_expirationTime = DateTime.Now.Add(cacheDuration);
}
public bool IsExpired { get { return DateTime.Now > _expirationTime; } }
public T Item
{
get
{
if (IsExpired)
throw new InvalidOperationException("Expired Cached Items cannot be retrieved.");
return _item;
}
}
}

Related

How to properly lock with concurrent multiple requests

I have an auto refresh cache in our system, which is running into some issues due to race conditions.
During start up the _internalCache which is a concurrent dictionary is empty.
This was implemented years ago as a generic auto refresh cache used across our system.
The refresh action which is causing a most of the trouble, refreshes a few thousand rows from the database.
public bool TryGet(TKey key, out TValue value)
{
if (_internalCache.TryGetValue(key, out value))
{
return true;
}
lock (_internalCache.SyncRoot)
{
this._refreshCacheAction(this._internalCache);
return _internalCache.TryGetValue(key, out value);
}
}
If multiple requests come in at the same time (which happens more often than I wish would) Then, we refresh our cache multiple times.
Edit:
After further discussion from the comments, it looks like this cache is Seriously broken. Several of our customers are experiencing timeouts, which I need a quick hotfix.
How can I prevent multiple refreshes to the cache?
(Jenky hacks are welcome)
In general the design looks flawed. Maybe even a standard component like ConcurrentDictionary or MemoryCache can be used.
However, one possible hotfix is to check again for the value in the internal cache inside the lock. This should reduce the number of times the refresh action is executed.
public bool TryGet(TKey key, out TValue value)
{
if (_internalCache.TryGetValue(key, out value))
{
return true;
}
lock (_internalCache.SyncRoot)
{
// cache has already been refreshed
if (_internalCache.TryGetValue(key, out value))
{
return true;
}
// refresh cache
this._refreshCacheAction(this._internalCache);
return _internalCache.TryGetValue(key, out value);
}
}
Be certain that the class containing TryGet is a singleton instance across all calls, in that it should only be created once during the application lifetime. A private instance constructor combined with a static property on the class that references the single instance, constructed in the static constructor of the class, is sufficient:
public class ASingletonClass
{
static ASingletonClass()
{
Instance = new ASingletonClass();
}
private ASingletonClass()
{
}
public static ASingletonClass Instance { get; private set; }
}
Also, replace the SyncRoot call with a new object field in your class set to new object(). Newer collections like ConcurrentDictionary don't support SyncRoot.

Create constructor(?) to retrieve object from cache or recreate if null

I'm building an intranet using C# webforms. I've got a list object with a bunch of users which I'm cacheing. I'm trying to create a constructor that will do the following when I reference MainADList:
if it exists in the cache and is not null, use it
else generate the list and cache it
I've got the code to do the caching and retrieving, but it isn't encapsulated nicely in a way that I'd like.
public Users MainADList = new Users();
private void GenerateADList()
{
MainADList = (Users) Cache["MainADList"];
if (MainADList == null || MainADList.Count == 0)
{
//generate the list....
Cache["MainADList"] = MainADList;
}
}
Thanks!
You can't create a constructor which does that. A constructor always creates a new object.
Instead, create a static factory method:
public static Users GetUsers()
{
// Consult the cache, and create a new instance if necessary.
}
This may be a singleton - but it certainly doesn't have to be. (I wouldn't artificially impose its singleton-ness unless I really had to. I'm not a big fan of the singleton pattern.)
Alternatively, instead of a static factory method, you could have an instance method in a factory class:
public class UsersFactory
{
// Construct it with a cache, or whatever's required
public Users GetUsers()
{
// Use the cache, or construct a new value.
}
}
Now this is more testable - because you're not relying on any static (global) state. Instead, you can create a new factory from a new cache in each test.
In all of these solutions, you need to consider what threading behaviour you want. If you want to make sure that you only construct the value once, you'll need to use Lazy<T>, static initializer guarantees, or locking.
One general pattern you could follow:
public class ClassName {
public static Object CachedObject {
get {
Object o = (Object)Cache['CacheKey'];
if (o == null)
{
o = GetData();
Cache["CacheKey"] = o;
}
return o;
}
}
}
And treat ClassName.CachedObject as though it's always, eternally, and magically populated.
What you want is known as a Singleton.
Basically what you should do with the code you already have is something like this:
public static GetList
{
get
{
//check if list exists and create it - so basically call your private constructor
//return cached list
}
}

Global thread-safe multi-value custom Dictionary with single instantiation

I would like to have a global object similar to a multi-value Dictionary that is shared among different Threads.
I would like the object to be created only once (for example getting the data from a Database) and then used by the different Threads.
The Object should be easily extendable with additional properties (currently have only JobName and URL).
If possible, I would prefer to avoid locking.
I am facing the following issues:
The current version displayed below is not Thread safe;
I cannot use a ConcurrentDictionary since I have extended the Dictionary object to allow multiple values for each key;
This is the object structure that should be modified easily:
public struct JobData
{
public string JobName;
public string URL;
}
I have extended the Dictionary object to allow multiple values for each key:
public class JobsDictionary : Dictionary<string, JobData>
{
public void Add(string key, string jobName, string url)
{
JobData data;
data.JobName = jobName;
data.URL = url;
this.Add(key, data);
}
}
Static class that is shared among Threads.
As you can see it creates a Dictionary entry for the specific Job the first time it is called for that Job.
For instance, the first time it is called for "earnings" it will create the "earnings" dictionary entry. This creates issues with Thread safety:
public static class GlobalVar
{
private static JobsDictionary jobsDictionary = new JobsDictionary();
public static JobData Job(string jobCat)
{
if (jobsDictionary.ContainsKey(jobCat))
return jobsDictionary[jobCat];
else
{
String jobName;
String url = null;
//TODO: get the Data from the Database
switch (jobCat)
{
case "earnings":
jobName="EarningsWhispers";
url = "http://www.earningswhispers.com/stocks.asp?symbol={0}";
break;
case "stock":
jobName="YahooStock";
url = "http://finance.yahoo.com/q?s={0}";
break;
case "functions":
jobName = "Functions";
url = null;
break;
default:
jobName = null;
url = null;
break;
}
jobsDictionary.Add(jobCat, jobName, url);
return jobsDictionary[jobCat];
}
}
In each Thread I get the specific Job property in this way:
//Get the Name
string JobName= GlobalVar.Job(jobName).JobName;
//Get the URL
string URL = string.Format((GlobalVar.Job(jobName).URL), sym);
How can I create a custom Dictionary that is "instantiated" once (I know it is not the right term since it is static...) and it is Thread-safe ?
Thanks
UPDATE
Ok, here is the new version.
I have simplified the code by removing the switch statement and loading all dictionary items at once (I need all of them anyway).
The advantage of this solution is that it is locked only once: when the dictionary data is added (the first Thread entering the lock will add data to the dictionary).
When the Threads access the dictionary for reading, it is not locked.
It should be Thread-Safe and it should not incur in deadlocks since jobsDictionary is private.
public static class GlobalVar
{
private static JobsDictionary jobsDictionary = new JobsDictionary();
public static JobData Job(string jobCat)
{
JobData result;
if (jobsDictionary.TryGetValue(jobCat, out result))
return result;
//if the jobsDictionary is not initialized yet...
lock (jobsDictionary)
{
if (jobsDictionary.Count == 0)
{
//TODO: get the Data from the Database
jobsDictionary.Add("earnings", "EarningsWhispers", "http://www.earningswhispers.com/stocks.asp?symbol={0}");
jobsDictionary.Add("stock", "YahooStock", "http://finance.yahoo.com/q?s={0}");
jobsDictionary.Add("functions", "Functions", null);
}
return jobsDictionary[jobCat];
}
}
}
If you are populating the collection once, you don't need any locking at all, since a Dictionary is thread-safe when it is only read from. If you want prevent multiple threads from initializing multiple times you can use a double-checked lock during initalization, like this:
static readonly object syncRoot = new object();
static Dictionary<string, JobData> cache;
static void Initialize()
{
if (cache == null)
{
lock (syncRoot)
{
if (cache == null)
{
cache = LoadFromDatabase();
}
}
}
}
Instead of allowing every thread to access the dictionary, hide it behind a facade that only exposes the operations you really need. This makes it much easier to reason about thread-safety. For instance:
public class JobDataCache : IJobData
{
readonly object syncRoot = new object();
Dictionary<string, JobData> cache;
public void AddJob(string key, JobData data)
{
lock (this.syncRoot)
{
cache[key] = data;
}
}
}
Trying to prevent locking without having measured that locking actually has a too big impact on performance is bad. Prevent doing that. Often using a simple lock statement is much simpler than writing lock-free code. There is a nasty problem with concurrency bugs compared to normal software bugs. They are very hard to reproduce and very hard to track down. If you can, prevent writing concurrency bugs. You can do this by writing the simplest code you can, even if it is slower. If it proves to be too slow, you can always optimize.
If you want to write lock-free code anyway, try using immutable data structures, or prevent changing existing data. This is one trick I used when writing the Simple Injector (a reusable library). In this framework, I never update the internal dictionary, but always completely replace it with a new one. The dictionary itself is therefore never changed, the reference to that instance is just replaced with a completely new dictionary. This prevents you from having to do locks completely. However, you must realize that it is possible to loose updates. In other words, when multiple threads are updating that dictionary, one can loose its changes, simply because each thread creates a new copy of that dictionary and adds its own value too its own copy, before making that reference public to other threads.
In other words, you can only use this method when external callers only read (and you can recover from lost changes, for instance by querying the database again).
UPDATE
Your updated version is still not thread-safe, because of the reasons I explained on #ili's answer. The following will do the trick:
public static class GlobalVar
{
private static readonly object syncRoot = new object();
private static JobsDictionary jobsDictionary = null;
public static JobData Job(string jobCat)
{
Initialize();
return jobsDictionary[jobCat];
}
private void Initialize()
{
// Double-checked lock.
if (jobsDictionary == null)
{
lock (syncRoot)
{
if (jobsDictionary == null)
{
jobsDictionary = CreateJobsDictionary();
}
}
}
}
private static JobsDictionary CreateJobsDictionary()
{
var jobs = new JobsDictionary();
//TODO: get the Data from the Database
jobs.Add("earnings", "EarningsWhispers", "http://...");
jobs.Add("stock", "YahooStock", "http://...");
jobs.Add("functions", "Functions", null);
return jobs;
}
}
You can also use the static constructor, which would prevent you from having to write the double checked lock yourself. However, it is dangarous to call the database inside a static constructor, because a static constructor will only run once and when it fails, the complete type will be unusable for as long as the AppDomain lives. In other words your application must be restarted when this happens.
UPDATE 2:
You can also use .NET 4.0's Lazy<T>, which is safer than a double checked lock, since it is easier to implement (and easier to implement correctly) and is is also thread-safe on processor architectures with weak memory models (weaker than x86 such as ARM):
static Lazy<Dictionary<string, JobData>> cache =
new Lazy<Dictionary<string, JobData>>(() => LoadFromDatabase());
1) Use singleton patern to have one instance (one of the ways is to use static class as you have done)
2) To make anything thread safe you should use lock or it's analog. If you are afraids of unnessessary locks do like this:
public object GetValue(object key)
{
object result;
if(_dictionary.TryGetValue(key, out result)
return result;
lock(_dictionary)
{
if(_dictionary.TryGetValue(key, out result)
return result;
//some get data code
_dictionary[key]=result;
return result;
}
}

Pros/Cons on Lists with subsidiary objects

I'm again in the position to figure a way out to handle lists with subsidiary objects on our business objects.
Actually, our code often looks like this:
public class Object
{
private List<SubsidiaryObject> subsidiaryObjects = null;
public List<SubsidiaryObject> SubsidiaryObjects
{
get
{
if (this.subsidiaryObjects == null)
{
this.subsidiaryObjects = DBClass.LoadListFromDatabase();
}
return this.subsidiaryObjects;
}
set
{
this.subsidiaryObjects = value;
}
}
}
The Con on this:
The property is referenced in presentation layer and used for DataBinding. Releasing the reference to the actual list and replacing it with a new one will end in an referenced list in the GUI that does not have anything left with the list on the object.
The Pro on this:
Easy way of reloading the list (just set the reference to null and then get it again).
I developed another class that uses the following pattern:
public class Object2
{
private readonly List<SubsidiaryObject> subsidiaryObjects = new List<SubsidiaryObject>();
public List<SubsidiaryObject> SubsidiaryObjects
{
get
{
return this.subsidiaryObjects;
}
}
public void ReloadSubsidiaryObjects()
{
this.SubsidiaryObjects.Clear();
this.SubsidiaryObjects.AddRange(DBClass.LoadListFromDatabase());
}
}
Pro on this:
Reference is continous.
The Con on this:
Reloading the list is more difficult, since it just cannot be replaced, but must be cleared/filled with reloaded items.
What is your preferred way, for what situations?
What do you see as Pro/Con for either of these to patterns?
Since this is only a general question, not for a specific problem, every answer is welcome.
Do you need the caller to be able to modify the list? If not you should consider returning IEnumerable<T> or ReadOnlyCollection instead. And even if you do, you will probably be better off making cover versions for Add/Remove so you can intercept modifications. Handing a reference to internal state is not a good idea IMO.
A third option would be to go with option 2, but to create a new instance of the Object2 type each time you need to repopulate the list. Without additional context for the question, that is the option I would select, but there may be reasons why you would want to hold on to the original instance.

collections and application wide use?

Here's a specific problem that I run into when creating objects, such as collections, that need to be available through the whole scope of the application.
I have the following class:
class UserDataCollection
{
List<UserData> Collection = new List<UserData>();
UserData current;
public UserData Current
{
get { return current; }
set
{
current = value;
}
}
public UserDataCollection( UserData userdata )
{
this.current = userdata;
}
public void Add ( UserData item )
{
Collection.Add(item);
}
}
Now for every UserData object I want to add, it's going to create a new List object each time I go UserDataCollection datacoll = new UserDataCollection(userdata);
So my objects will never be added to the same collection, which is not the point of this collection.
Is this then a good singleton case or just create the object at Application Init and use the same object throughout?
What's the best design practice for something like this?
You could just make the list static. Then there will only ever be one collection.
It depends
If it's a web application, you can create your collection on application start and store it into Application property of HttpContext. If not, you can use a singleton or an IoC container and configure it to always return the same instance of the object.
P.S : If multiple threads of the application will run simultaniously, by sure to use a lock before updating the collection.
Hope it will help.
Collections like this are for multiple objects obviously, so you would instantiate them where you are creating a ... collection of objects... If you want to use a ctor, then it should take as it's parameter a ... collection or enumerable set of those objects...
// Inheriting from List<UserData> eliminates need for most of your code
class UserDataCollection: List<UserData>
{
public UserDataCollection(IEnumerable<UserData> users)
{
foreach (UserData usr in users)
Add(usr);
}
}
If there will only ever be one UserDataCollection per application then I don't see why not make it a singleton.
I like the idea of a Singleton here, if you only want one for your entire application. If you are using this in an ASP.NET application, you will have to watch out with Singletons because static variables are like saving data in Application state...which is probably what you want...but not easily noticeable to the outside world (maintainability issue).

Categories