Reputation: 1916
I have a slow and expensive method that return some data for me:
public Data GetData(){...}
I don't want to wait until this method will execute. Rather than I want to return a cached data immediately.
I have a class CachedData
that contains one property Data cachedData
.
So I want to create another method public CachedData GetCachedData()
that will initiate a new task(call GetData
inside of it) and immediately return cached data and after task will finish we will update the cache.
I need to have thread safe GetCachedData()
because I will have multiple request that will call this method.
I will have a light ping "is there anything change?" each minute and if it will return true (cachedData != currentData) then I will call GetCachedData()
.
I'm new in C#
. Please, help me to implement this method.
I'm using .net framework 4.5.2
Upvotes: 1
Views: 313
Reputation: 4382
If you will not call GetCachedData at the same time, you may not use lock. If data is null (for sure first run) we will wait long method to finish its work.
public class SlowClass
{
private static object _lock;
private static Data _cachedData;
public SlowClass()
{
_lock = new object();
}
public void GetCachedData()
{
var task = new Task(DoStuffLongRun);
task.Start();
if (_cachedData == null)
task.Wait();
}
public Data GetData()
{
if (_cachedData == null)
GetCachedData();
return _cachedData;
}
private void DoStuffLongRun()
{
lock (_lock)
{
Console.WriteLine("Locked Entered");
Thread.Sleep(5000);//Do Long Stuff
_cachedData = new Data();
}
}
}
I have tested on console application.
static void Main(string[] args)
{
var mySlow = new SlowClass();
var mySlow2 = new SlowClass();
mySlow.GetCachedData();
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
mySlow.GetData();
mySlow2.GetData();
}
mySlow.GetCachedData();
Console.Read();
}
Upvotes: 1
Reputation: 16017
The basic idea is clear:
Data
property which is wrapper around an expensive function call.That seems like a straight-forward design. At some point you may want to use events, but that can be added later.
Depending on the circumstances it may be necessary to make access to the property thread-safe. I think that if the Data
cache is a simple reference and no other data is updated together with it, a lock is not necessary, but you may want to declare the reference volatile
so that the reading thread does not rely on a stale cached (ha!) version. This post seems to have good links which discuss the issues.
Upvotes: 2
Reputation: 454
Maybe you can use the MemoryCache class, as explained here in MSDN
Upvotes: -1