Lifecycle of Static Variables - c#

Is there any way to set the life cycle of a static variable - ie: how long it's kept alive before being reset? I was hoping there may be an attribute which can be applied.

The lifetime of a value in a Static variables is the same as it's containing AppDomain. Ie. if you get a new AppDomain (because your IIS application restarts), you get a new copy of the static variable.

Static members are associated with the type itself, not with an instance of the type. Therefore their lifecycle is limited to the timing and ordering of their creation, and they don't get "reset" by instances of the type.

In my case, as I'm using ASP.NET, the item in question should remain 'live' for the lifecycle of one request, so after thinking about it the HttpContext["Items"] collection would be best. Eg, instead if:
private static SomeObject _books;
protected static SomeObject Books
{
get
{
if (_books == null) {
_books = new SomeObject();
}
return _books ;
}
}
protected static SomeObject AVariable
{
get
{
SomeObject books = HttpContext.Current.Items["books"] as SomeObject;
if (books == null) {
books = new SomeObject();
HttpContext.Current.Items["books"] = books;
}
return books;
}
}

A static variable is held for the lifespan of the application and shared between all threads. It is only reset when the application restarts (a web.config change for example).
If this is for something like caching I'd suggest setting a timer to update the value at regular intervals.

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.

Values fetched from database and assigned to variables do not persist across layers

I have a class like this and the purpose is to set these Boolean values in the data layer with purpose of persisting these values in through out application's life cycle.
public class ProjectFeatureIndicatorMetadata
{
public bool? SprcCustomIncludesInd;
public bool? SprcCustomVariablesInd;
public bool? SprcRatingFlowInd;
public bool? SprcFactorSetsGenerationInd;
public static void SetFeatureIndicatorValues(string name, bool value)
{
ProjectFeatureIndicatorMetadata indicators = new Data.ProjectFeatureIndicatorMetadata();
if(name == "SprcCustomIncludesInd") { indicators.SprcCustomIncludesInd = value; }
if(name == "SprcCustomVariablesInd") { indicators.SprcCustomVariablesInd = value; }
if(name == "SprcRatingFlowInd") { indicators.SprcRatingFlowInd = value; }
if(name == "SprcFactorSetsGenerationInd") { indicators.SprcFactorSetsGenerationInd = value; }
}
}
Then I have the data layer, pretty straight forward. I can confirm that database call is made and values are being fetched and at this level, the indicators are assigned values:
public void GetCachedProjectFeatureIndicatorsStatus(ProjectIdentifier projectId)
{
ProjectFeatureIndicatorMetadata indicatorData = new ProjectFeatureIndicatorMetadata();
GetSpHelper().ExecuteReader(
spName: "ITV.usp_ProjectFeatureIndicators_GetByProjectId",
parmsDg: parms => parms.AddWithValue("#ProjectId", projectId.Guid),
methodDg: reader =>
{
while (reader.Read())
{
ProjectFeatureIndicatorMetadata.SetFeatureIndicatorValues(
"SprcCustomVariablesInd", reader.Column<bool>("SprcCustomVariablesInd"));
ProjectFeatureIndicatorMetadata.SetFeatureIndicatorValues(
"SprcRatingFlowInd", reader.Column<bool>("SprcRatingFlowInd"));
ProjectFeatureIndicatorMetadata.SetFeatureIndicatorValues(
"SprcFactorSetsGenerationInd", reader.Column<bool>("SprcFactorSetsGenerationInd"));
ProjectFeatureIndicatorMetadata.SetFeatureIndicatorValues(
"SprcCustomIncludesInd", reader.Column<bool>("SprcCustomIncludesInd"));
}
return true;
});
}
The application start up class calls middle layer through an interface. Below is hot it's implemented. The four 'vars' are just a test code but the bottom line is, values for the indicator variables are null. And I don't know why.
Data.GetCachedProjectFeatureIndicatorStatus(project);
ProjectFeatureIndicatorMetadata indicators = new ProjectFeatureIndicatorMetadata();
var sprcCustomIncludesInd = indicators.SprcCustomIncludesInd;
var sprcCustomVariablesInd = indicators.SprcCustomVariablesInd;
var sprcFactorSetsGenerationInd = indicators.SprcFactorSetsGenerationInd;
var sprcRatingFlowInd = indicators.SprcRatingFlowInd;
The Data object is class variable in the start up class:
private ProjectData Data
{
[Pure, DebuggerStepThrough]
get { return ProjectDataProvider.ProjectData; }
}
ProjectData is large class that holds lot of other stuff but my code only has this call to the interface:
public void GetCachedProjectFeatureIndicatorStatus(ProjectIdentifier projectId)
{
_server.GetCachedProjectFeatureIndicatorStatus(projectId);
}
Then another class that has the following method that is the main logic for this task:
public void GetCachedProjectFeatureIndicatorStatus(ProjectIdentifier projectId)
{
ProjectFeatureIndicatorMetadata indicators = new ProjectFeatureIndicatorMetadata();
using (new WriteLock(_lock))
{
if (indicators.SprcCustomIncludesInd != null ||
indicators.SprcCustomVariablesInd != null ||
indicators.SprcFactorSetsGenerationInd != null ||
indicators.SprcRatingFlowInd != null)
{
return;
}
else
{
GetProjectFeatureIndicatorsStatus(projectId);
return;
}
}
}
public virtual void GetProjectFeatureIndicatorsStatus(Guid projectId)
{
string PROJECT_SERVER_SQL_CONNECTION_STRING = ConfigurationManager.ConnectionStrings["ConfigConnectionString"].ConnectionString;
var configConnectionFactory = new ManualConnectionFactory(PROJECT_SERVER_SQL_CONNECTION_STRING);
var projectFeatureIndicatorTable = new ProjectFeatureIndicatorsTable(configConnectionFactory);
projectFeatureIndicatorTable.GetCachedProjectFeatureIndicatorsStatus(projectId);
}
I don't fully understand some of your code, like why in your method that has a DataReader, you make a new object instance of ProjectFeatureIndicatorMetaData but then you start looping the reader and make a bunch of static calls like:
while (reader.Read())
{
ProjectFeatureIndicatorMetadata.SetFeatureIndicatorValues(
"SprcCustomVariablesInd", reader.Column<bool>("SprcCustomVariablesInd"));
This won't do anything with the instance you just made, and you don't appear to access the static again outside the data reading loop, nor do you return the instance you made - you instead make another new instance in a different method and then try to access its properties (which will be null)
ProjectFeatureIndicatorMetadata indicators = new ProjectFeatureIndicatorMetadata();
using (new WriteLock(_lock))
{
if (indicators.SprcCustomIncludesInd != null ||
Ultimately if you want your data to travel round your app you have to make an instance, fill it with data and then pass it somewhere (call a method and pass it as a parameter/return it from a method to a method that captures the return value). Right now you have some static things, some non static things and whenever you want to do anything you make a new instance, fill it with data and then immediately throw it away, or you make a new instance and try to read from it as though you expect it to contain data. It's like you expect statics to be some sort of defaulting mechanism that, once called, mean that every new instance you make of that type gets the "defaults" that were set by calling the static methods - statics aren't like that. Statics are more like "there is one instance of the static stuff, that the runtime makes for you, but to access it you must always use it in a static way(no instance variables, just the type name)" - you're mixing "new" (==make a new instance) with static(==a single already existing instance the runtime made)
I'd generally advise to stay away from statics as a way of passing data around; as global variables they're almost always a bad idea in potentially concurrent situations. If you're setting up a cache of commonly used data at startup they may make sense but it introduces a high level of coupling to your classes; every class becomes dependent on the static and has to know what it is and cannot function without it. If you code in a more Dependency Injection style where you give every class instance the data it needs to function when you construct it, you don't get to a place where all classes depend on one - instead they use the data they're given and it isn't mandated how it gets it - you can use that class in a future project just by dropping it in and providing the same initial data from a different way

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.

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

Categories