Consider the following scenario
private static ConcurrentDictionary<string, ConcurrentDictionary<string, string>> CachedData;
where multiple threads access this variable via a method calling
ConcurrentDictionary<string, string> dic = CachedData.GetorAdd(key, HeavyDataLoadMethod())
where this method does some heavy weight operations to retrieve the data
private ConcurrentDictionary<string, string> HeavyDataLoadMethod()
{
var data = new ConcurrentDictionary<string,string>(SomeLoad());
foreach ( var item in OtherLoad())
//Operations on data
return data;
}
My problem here is that if I useGetorAdd
the HeavyDataLoadMethod
gets executed even if it is not needed.
I was wondering if there is some way to take advantage of deferred execution in this case and make the HeavyDataLoadMethod
deferred so it is not executed until it is really needed.
(Yes, I know this is as simple as checking with a ContainsKey and forget about it, but I'm curious about this approach)
In Deferred Execution, the query is not executed when declared. It is executed when the query object is iterated over a loop. In Immediate Execution, the query is executed when it is declared.
The basic difference between a Deferred execution vs Immediate execution is that Deferred execution of queries produce a sequence of values, whereas Immediate execution of queries return a singleton value and is executed immediately.
Benefits of Deferred Execution –It avoids unnecessary query execution and hence improves performance. Query construction and Query execution are decoupled, so we can create the LINQ query in several steps. A deferred execution query is reevaluated when you re-enumerate – hence we always get the latest data.
Immediate execution is the reverse of deferred execution. It forces the LINQ query to execute and gets the result immediately. The 'To' conversion operators execute the given query and give the result immediately.
You can pass a delegate, instead of the direct function call:
Either pass in:
// notice removal of the `()` from the call to pass a delegate instead
// of the result.
ConcurrentDictionary<string, string> dic = CachedData.GetorAdd(key, HeavyDataLoadMethod)
or
ConcurrentDictionary<string, string> dic = CachedData.GetorAdd(key,
(key) => HeavyDataLoadMethod())
That way you pass in the pointer to the method, instead of the method results. Your heavy data load method must accept a parameter with the value of "key".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With