How to properly lock with concurrent multiple requests - c#

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.

Related

Solution for thread safe read write updates to static variables with read write synchronization

In my project I'm using some static variables which I use for storing values during the running lifetime of the application. Now, 99% of the time I'm only reading these values but from time to time I also need to update them and this will happen from different threads.
When thinking about what might happen with two different threads trying to access the same property e.g. concurrent read/write, I started to conclude that some form of synchronization would needed in order to avoid unexpected values being returned between different process or some risk of race conditions.
In essence I needed to derive a single source of truth. I realize that some properties are atomic like booleans, but my methodology mostly applies for the purpose of strings.
One of the challenges is that these static variables are referenced in many places and between different classes, so I also had to figure out an efficient way to solve this challenge without lots of code re-write.
I've decided to use concurrent dictionaries:
public static readonly ConcurrentDictionary<string, string> AppRunTimeStringDictionary = new();
public static readonly ConcurrentDictionary<string, int> AppRunTimeIntegerDictionary = new();
public static readonly ConcurrentDictionary<string, bool> AppRunTimeBooleanDictionary = new();
In my program.cs file, during the earliest stages of startup I simply add all of the properties needed for the running app:
DeviceProvisioning.AppRunTimeBooleanDictionary.TryAdd("UseGpsReceiver", false);
DeviceProvisioning.AppRunTimeStringDictionary.TryAdd("Latitude", String.Empty);
DeviceProvisioning.AppRunTimeStringDictionary.TryAdd("Longitude", String.Empty);
Then in one of my classes I hard code these properties:
public static bool? UseGpsReceiver
{
get
{
if (AppRunTimeBooleanDictionary.TryGetValue("UseGpsReceiver", out var returnedValue))
return returnedValue;
return null;
}
}
public static string? Latitude
{
get
{
if (AppRunTimeStringDictionary.TryGetValue("Latitude", out var returnedValue))
return returnedValue;
return null;
}
}
public static string? Longitude
{
get
{
if (AppRunTimeStringDictionary.TryGetValue("Longitude", out var returnedValue))
return returnedValue;
return null;
}
}
Now for updating these properties, which happens rarely but will be done every now and then, I'm updating these in just one location i.e. using a single method. This way I can use this common method and simply add more prperties to the switch case over time.
public static void SetRunTimeSettings(string property, object value)
{
switch (property)
{
case "UseGpsReceiver":
// code block
if (AppRunTimeBooleanDictionary.TryGetValue("UseGpsReceiver", out var useGpsReceiver))
{ AppRunTimeBooleanDictionary.TryUpdate("UseGpsReceiver", (bool)value, useGpsReceiver); }
break;
case "Latitude":
// code block
if (AppRunTimeStringDictionary.TryGetValue("Latitude", out var latitude))
{ AppRunTimeStringDictionary.TryUpdate("Latitude", (string)value, latitude); }
break;
case "Longitude":
// code block
if (AppRunTimeStringDictionary.TryGetValue("Latitude", out var longitude))
{ AppRunTimeStringDictionary.TryUpdate("Latitude", (string)value, longitude); }
break;
}
}
If I want to update a property then I simply invoke the method as such:
MyClassName.SetRunTimeSettings("UseGpsReceiver", true);
MyClassName.SetRunTimeSettings("Latitude", "51.1234");
MyClassName.SetRunTimeSettings("Longitude", "51.5678");
Because the properties themselves are public static then I can use the getter from anywhere in the app.
From my initial testing, everything seems to work.
Perceived advantages in this approach:
Using a separate dictionary for each type of property collection i.e. strings/integers etc, means I can simply add more properties to the dictionary any time in the future without the need for referencing a model class in the dictionary, as opposed to the dictionary below:
public static readonly ConcurrentDictionary<string, myModelClass> AppRunTimeStringDictionary = new();
Use of the concurrent dictionary (my understanding) is that any process trying to read the property value from the dictionary will always get the latest value, if a property is being updated then I have less risk in reading an old value. Not such an issue for structured logging but if I was storing keys/secrets/connection strings or anything else, reading an old value might stop some process from being able to function correctly.
Using the concurrent dictionary means I don't have to hand craft my own locking mechanisms, which many people seem not to like doing.
Dictionary applies its own internal locks on the individual objects, so any property not being updated can still be read by other processes without much delay.
If the public static getter ever returned a null value, my thoughts are it would be better to return a null value rather than returning the wrong value. I could always implement some kind of polly or retry mechanism somewhere from the calling process, some short delay before trying to retrieve the property value again (by which time it should have been updated from the other thread that was currently updating it)
Appreciate there will be other ways to approach this, so really what I'm asking here is whether anyone sees any issue in my approach?
I'm not planning to add that many properties to each dictionary, I just want a way to ensure that reads and writes are happening with some form of synchronization and order.
Your SetRunTimeSettings is awful. It relies on methods that follow the Try* pattern, but it itself does not. Also doing a TryGetValue just to then be able to call TryUpdate is just throwing away all of the value of Try* operators anyway. It's a hack.
And you have a clear bug in the code for the "Longitude" case - you're updating "Latitude" inside.
I'd suggest going old school and just do this:
private static bool? _UseGpsReceiver;
private readonly static object _UseGpsReceiverLock = new();
public static bool? UseGpsReceiver
{
get { lock (_UseGpsReceiverLock) return _UseGpsReceiver; }
set { lock (_UseGpsReceiverLock) _UseGpsReceiver = value; }
}
private static string? _Latitude;
private readonly static object _LatitudeLock = new();
public static string? Latitude
{
get { lock (_LatitudeLock) return _Latitude; }
set { lock (_LatitudeLock) _Latitude = value; }
}
private static string? _Longitude;
private readonly static object _LongitudeLock = new();
public static string? Longitude
{
get { lock (_LongitudeLock) return _Longitude; }
set { lock (_LongitudeLock) _Longitude = value; }
}
If you don't want to repeat all of the locks then maybe a Locked<T> class might be of use:
public struct Locked<T>
{
public Locked(T value)
{
_value = value;
}
private T _value;
private readonly object _gate = new();
public T Value
{
get { lock (_gate) return _value; }
set { lock (_gate) _value = value; }
}
}
Then you can write this:
private static Locked<bool?> _UseGpsReceiver;
public static bool? UseGpsReceiver
{
get { return _UseGpsReceiver.Value; }
set { _UseGpsReceiver.Value = value; }
}
private static Locked<string?> _Latitude;
public static string? Latitude
{
get { return _Latitude.Value; }
set { _Latitude.Value = value; }
}
private static Locked<string?> _Longitude;
public static string? Longitude
{
get { return _Longitude.Value; }
set { _Longitude.Value = value; }
}
If you are only setting a single string / int / bool at a time, then you don't need to any thread safety. If you are assigning any single value smaller than a machine word, any reading thread will either see the before value or the after value.
However it looks like you intend to set three values at the same time;
MyClassName.SetRunTimeSettings("UseGpsReceiver", true);
MyClassName.SetRunTimeSettings("Latitude", "51.1234");
MyClassName.SetRunTimeSettings("Longitude", "51.5678");
And I assume you want any reader to see either the old values or the new values. In this case you would need some thread synchronisation around every read / write. Which your current code doesn't have.
You could instead store the three values in a class, then update the reference to that instance in one write operation.
public class GpsSettings{
public bool UseGpsReceiver { get; init; }
public double Latitude { get; init; }
public double Longitude { get; init; }
public static GpsSettings Current;
}
...
// write
GpsSettings.Current = new GpsSettings {
UseGpsReceiver = true,
Latitude = 51.1234,
Longitude = 51.5678
};
// read
var gps = GpsSettings.Current;
var location = $"{gps.Latitude}, {gps.Longitude}";
// but never do this;
var location = $"{GpsSettings.Current.Latitude}, {GpsSettings.Current.Longitude}";
Not everyone would agree with me on this one but my personal approach would be to have a single dictionary of the following type:
Dictionary<string, object>
Wrapped in a separate class with the following methods such as AddValue, GetValue, HasKey, HasValue, and UpdateValue with lock statements. Also notice that you'll have to use somewhat generic methods in order to be able to retrieve the value with the actual type and a default value. For example:
public static T GetValue<T>(string key, T defaultValue)
Also, I don't see a problem with your approach but if you want to synchronize things then you'll need n dedicated locks for n dictionaries which I don't think is a clean way; unless I'm missing something, and of course registering multiple dictionaries in design time can be a headache.
Alternatively to using multiple ConcurrentDictionary<string, T> collections, or a single ConcurrentDictionary<string, object>, or the Locked<T> struct shown in Enigmativity's answer, you could just store the values in immutable and recyclable Tuple<T> instances, and store these in private volatile fields:
private static volatile Tuple<bool?> _UseGpsReceiver;
public static bool? UseGpsReceiver
{
get { return _UseGpsReceiver?.Item1; }
set { _UseGpsReceiver = new(value); }
}
private static volatile Tuple<string> _Latitude;
public static string Latitude
{
get { return _Latitude?.Item1; }
set { _Latitude = new(value); }
}
private static volatile Tuple<string> _Longitude;
public static string Longitude
{
get { return _Longitude?.Item1; }
set { _Longitude = new(value); }
}
Pros: Both the reading and the writing are lock-free. An unlimited number of readers and writers can read and update the values at the same time, without contention.
Cons: Every time a value is updated, a new Tuple<T> is instantiated, adding pressure on the .NET garbage collector. This reduces the appeal of this approach in case the values are updated too frequently. Also if you have dozens of properties like these, it might be easy to introduce subtle bugs by omitting the important volatile keyword by mistake.

Caching with UnitOfWork

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;
}
}
}

A static property in static class when used concurrently

I have a static class 'Logger' with a public property called 'LogLevels' as in code below.
When the property is used concurrently in a multi-user or multi-threaded environment, could it cause problems?
Do I need to use thread synchronization for the code within the property 'LogLevels'?
public class Logger
{
private static List<LogLevel> _logLevels = null;
public static List<LogLevel> LogLevels
{
get
{
if (_logLevels == null)
{
_logLevels = new List<LogLevel>();
if (!string.IsNullOrWhiteSpace(System.Configuration.ConfigurationManager.AppSettings["LogLevels"]))
{
string[] lls = System.Configuration.ConfigurationManager.AppSettings["LogLevels"].Split(",".ToCharArray());
foreach (string ll in lls)
{
_logLevels.Add((LogLevel)System.Enum.Parse(typeof(LogLevel), ll));
}
}
}
if (_logLevels.Count == 0)
{
_logLevels.Add(LogLevel.Error);
}
return _logLevels;
}
}
}
UPDATE: I ended up using thread synchronization to solve concurrency problem in a static class, as in code below.
public class Logger
{
private static readonly System.Object _object = new System.Object();
private static List<LogLevel> _logLevels = null;
private static List<LogLevel> LogLevels
{
get
{
//Make sure that in a multi-threaded or multi-user scenario, we do not run into concurrency issues with this code.
lock (_object)
{
if (_logLevels == null)
{
_logLevels = new List<LogLevel>();
if (!string.IsNullOrWhiteSpace(System.Configuration.ConfigurationManager.AppSettings["SimpleDBLogLevelsLogger"]))
{
string[] lls = System.Configuration.ConfigurationManager.AppSettings["SimpleDBLogLevelsLogger"].Split(",".ToCharArray());
foreach (string ll in lls)
{
_logLevels.Add((LogLevel)System.Enum.Parse(typeof(LogLevel), ll));
}
}
}
if (_logLevels.Count == 0)
{
_logLevels.Add(LogLevel.Error);
}
}
return _logLevels;
}
}
}
When the property is used concurrently in a multi-user or multi-threaded environment, could it cause problems?
Absolutely. List<T> is not designed for multiple threads, except for the case where there are just multiple readers (no writers).
Do I need to use thread synchronization for the code within the property 'LogLevels'?
Well that's one approach. Or just initialize it on type initialization, and then return a read-only wrapper around it. (You really don't want multiple threads modifying it.)
Note that in general, doing significant amounts of work in a static constructor is a bad idea. Are you happy enough that if this fails, every access to this property will fail, forever?
This code posses race conditions and cannot be safely executed from multiple threads. The primary problem is the List<T> type is not thread safe yet this code will freely write to. This mean the writes can occur in parallel and hence break the implicit contract of List<T>
The short answer is "yes" and "yes" you do need threads synchronization.
The other question is, why re-invent the wheel? You can use something like log4net or .NET logging framework.

How to synchronize a collection of values in C#

I have inherited some code that has a set of real-time values that are captured over a serial link that runs on a separate thread:
class Data
{
public static int nFooCount;
public static decimal meanValue;
// Lots more of a variety of types.
}
The thread just stores the data into the field with no locking or other synchronization. Looks like a whole sea of race conditions to me. So I want to add some safety to it. The question is, what's best?
I could make the int fields volatile. Can't do that with the decimal types, though. Interlocked can help with that, albeit messily, using boxing. Or I could add a lock object
private static readonly object lockObj = new object();
and then accessor everything. But this locks all the fields even when it will only modify one at a time. I can't lock on primitives and that would be bad form anyway, and adding a lock object for every field would look wasteful. So is there a better way?
You could lock according to required access level using ReaderWriterLockSlim. You could do this better by turning them into a property:
public int Something
{
get {
locker.EnterReadLock();
try {
return something;
} finally {
locker.ExitReadLock();
}
}
set {
locker.EnterWriteLock();
try {
something = value;
} finally {
locker.ExitWriteLock();
}
}
}
This allows for multiple reads and single writes.

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;
}
}

Categories