Proper class definition and usage - thread safe - ASP.net - c#

I wonder how to define a class properly and use it safely. I mean thread safely when thousands of concurrent calls are being made by every website visitor.
I made myself something like below but i wonder is it properly built
public static class csPublicFunctions
{
private static Dictionary<string, clsUserTitles> dicAuthorities;
static csPublicFunctions()
{
dicAuthorities = new Dictionary<string, clsUserTitles>();
using (DataTable dtTemp = DbConnection.db_Select_DataTable("select * from myTable"))
{
foreach (DataRow drw in dtTemp.Rows)
{
clsUserTitles tempCLS = new clsUserTitles();
tempCLS.irAuthorityLevel = Int32.Parse(drw["Level"].ToString());
tempCLS.srTitle_tr = drw["Title_tr"].ToString();
tempCLS.srTitle_en = drw["Title_en"].ToString();
dicAuthorities.Add(drw["authorityLevel"].ToString(), tempCLS);
}
}
}
public class clsUserTitles
{
private string Title_tr;
public string srTitle_tr
{
get { return Title_tr; }
set { Title_tr = value; }
}
private string Title_en;
public string srTitle_en
{
get { return Title_en; }
set { Title_en = value; }
}
private int AuthorityLevel;
public int irAuthorityLevel
{
get { return AuthorityLevel; }
set { AuthorityLevel = value; }
}
}
public static clsUserTitles returnUserTitles(string srUserAuthority)
{
return dicAuthorities[srUserAuthority];
}
}
Dictionary will be initialized only 1 time. No add remove update later.

Dictionary supports thread safe reading. Here is the proof from MSDN:
A Dictionary can support multiple readers concurrently,
as long as the collection is not modified. Even so, enumerating
through a collection is intrinsically not a thread-safe procedure. In
the rare case where an enumeration contends with write accesses, the
collection must be locked during the entire enumeration. To allow the
collection to be accessed by multiple threads for reading and writing,
you must implement your own synchronization.
So, if you are planning to only read data from it, it should work. However, I do not believe that your dictionary is filled only once and won't be modified during your application work. in this case, all other guys in this thread are correct, it is necessary to synchronize access to this dictionary and it is best to use the ConcurrentDictionary object.
Now, I want to say a couple of words about the design itself. If you want to store a shared data between users, use ASP.NET Cache instead which was designed for such purposes.

A quick look through your code and it seems to me that your first problem will be the publicly available dictionary dicAuthorities. Dictionaries are not thread safe. Depending on what you want to do with that Dictionary, you'll need to implement something that regulates access to it. See this related question:
Making dictionary access thread-safe?

As the others have said, Dictionary<TKey,TValue> is not inherently thread-safe. However, if your usage scenario is:
Fill the dictionary on startup
Use that dictionary as lookup while the application is running
Never add or remove values after startup
than you should be fine.
However, if you use .net 4.5, I would recommend making #3 explict, by using a ReadOnlyDictionary
So, your implementation might look like this (changed the coding style to more C# friendly)
private static readonly ReadOnlyDictionary<string, UserTitles> authorities;
static PublicFunctions()
{
Dictionary<string, UserTitles> authoritiesFill = new Dictionary<string, clsUserTitles>();
using (DataTable dtTemp = DbConnection.db_Select_DataTable("select * from myTable"))
{
foreach (DataRow drw in dtTemp.Rows)
{
UserTitles userTitle = new UserTitles
{
AuthorityLevel = Int32.Parse(drw["Level"].ToString()),
TitleTurkish = drw["Title_tr"].ToString();
TitleEnglish = drw["Title_en"].ToString();
}
authoritiesFill.Add(drw["authorityLevel"].ToString(), userTitle);
}
}
authorities = new ReadOnlyDictionary<string, UserTitles>(authoritiesFill);
}
I've also added a readonly modifier to the declaration itself, because this way you can be sure that it won't be replaced at runtime by another dictionary.

No you code is not thread safe.
[EDIT does not apply - set/created inside static constructor] Dictionary (as pointed by System Down answer) is not thread safe while being updated. Dictionary is not read only - hence no way to guarantee that it is not modified over time.
[EDIT does not apply - set/created inside static constructor] Initialization is not protected by any locks so you end-up with multiple initializations at the same time
Your entries are mutable - so it is very hard to reason if you get consistent value of each entry
[EDIT does not apply - only modified in static constructor] Field that holds dictionary not read-only - depending on code you may end-up with inconsistent data if not caching pointer to dictionary itself.
Side note: try to follow coding guidelines for C# and call classes starting with upper case MySpecialClass and have names that reflect purpose of the class (or clearly sample names).
EDIT: most of my points do not apply as the only initialization of the dictionary is inside static constructor. Which makes initialization safe from thread-safety point of view.
Note that initialization inside static constructor will happen at non-deterministic moment "before first use". It can lead to unexpected behavior - i.e. when access to DB may use wrong "current" user account.

The answer to your question is no, it's not thread safe. Dictionary is not a thread-safe collection. If you want to use a thread-safe dictionary then use ConcurrentDictionary.
Besides that, it's difficult to say whether your csPublicFunctions is thread-safe or not because it depends on how you handle your database connections inside the call to DbConnection.db_Select_DataTable

There is not thread-safe problem only with public Dictionary.
Yes, dictionary filling is thread-safe. But another modification of this dictionary is not thread safe. As was wrote above - ConcurrentDictionary could help.
Another problem that your class clsUserTitles is not thread-safe too.
If clsUserTitles is using only for reading you could make each property setter of clsUserTitles private. And initialize these properties from clsUserTitles constructor.

Related

When do I know I have to lock a dictionary in a c# base class?

I'm trying to understand something about multi-threading in a C# application. I inherited an application that has the following code in a base class called SecurityComponentBase:
m_permissionsLock.EnterWriteLock();
try
{
if (m_grantedPermissions.Count > 0)
{
m_grantedPermissions.Clear();
m_loggingComponent.WriteSecurityLog(
"Security permissions cleared for user: " + CurrentLoggedUser.Username);
}
foreach (var p in permisions)
{
m_loggingComponent.WriteSecurityLog("Security permission: "+ p.PermissionName + " Granted to user: " + userName);
m_grantedPermissions.Add(p.PermissionName, p);
}
}
finally
{
m_permissionsLock.ExitWriteLock();
}
The m_permissionsLock is defined as:
private readonly ReaderWriterLockSlim m_permissionsLock = new ReaderWriterLockSlim();
The m_grantedPermissions is defined as:
private readonly Dictionary<string, Permission> m_grantedPermissions = new Dictionary<string, Permission>();
When would a developer know that he has to wrap this dictionary in a lock? To me, I wouldn't even know where other threads would be coming from. Remember I'm new to this multi-threading thing. But how would I even know that I have to do this?
When would a developer know that he has to wrap this dictionary in a lock?
We observe the following principles:
Get a Write lock when modifying the dictionary, or its contents, in any way.
Get a Read lock when accessing the dictionary or its contents, without modifying either.
Control access to the dictionary, so only we can access it, in this class. Access to the dictionary must go through us.
Point #1 is demonstrated in the code you pasted. Point #3 is also demonstrated in your code with the private declaration of m_grantedPermissions. Only the code in this class can access the private member.
To me, I wouldn't even know where other threads would be coming from.
Where calling threads come from isn't relevant. When a thread executes code from this class, you, the developer, can spot where you are reading and writing the dictionary, and you can wrap each reference accordingly. Remember, only this class can access the dictionary. You don't need to search your entire solution. Just the one class.
In Visual Studio, double-clicking the m_grantedPermissions should highlight every instance; you can also search for "m_grantedPermissions" to find every reference to it.
Each reference to m_grantedPermissions should be wrapped in the proper lock.

Ensure class is thread safe with only properties (any .NET 4.0 techniques specifically meant for this ?)

I have a class with two properties and two methods. Like the one below for example. (please ignore the data types or return types, it's just a typical scenario)
// The methods could be invoked by multiple threads
public class Stock
{
private static int FaceValue {get; set;}
private static int Percent (get; set;}
// method that updates the two properties
Public void UpdateStock()
{
FaceValue += 1;
Percent = FaceValue * 100;
}
// method that reads the two properties
public int[] GetStockQuote()
{
return new int[] { FaceValue, Percent};
}
}
I need to ensure this class is thread safe. I could use lock(obj) in both the methods as one technique to make it threadsafe but what would be the best technique to make it thread safe, considering the following:
There are only two properties that is read/updated. So, not sure if locking inside the methods is a good technique.
Will it be enough if I just make the properties thread safe rather than the methods or the class ?
Also, is there a way to make the whole class thread safe rather than individual methods or properties ? Any recommended lock techniques from .Net 4.0 ?
Just wondering if I am thinking through this right or may be I am over complicating it considering these. Many thanks in advance to help me get this clear.
Mani
In general, a lock is probably the simplest approach here.
A potentially better alternative would be to make this class immutable. If you make it so you can't change the values within the class once it's created, you no longer have to worry when reading the values, as there's no way for them to be modified.
In this case, that could be done by having a constructor that takes the two values, and changing UpdateStock to be more like:
public Stock GetUpdatedStock()
{
// Create a new instance here...
return new Stock(this.FaceValue + DateTime.Now.MilliSecond, this.FaceValue * 100);
}
Edit:
Now that you've made FaceValue and Percent static, you will need synchronization. A lock is likely the simplest option here.
With a single value, you could potentially use the Interlocked class to handle updates atomically, but there is no way to do an atomic update of both values*, which is likely required for the thread safety to be done properly. In this case, synchronizing via a lock will solve your issue.
*Note: This could possibly be done without a lock via Interlocked.CompareExchange if you put both values within a class, and exchanged the entire class instance - but that's likely a lot more trouble than it's worth.
There is no silver bullet solution for making thread safe, each scenario needs it's own solution. The most obvious is to use a lock, but in your example, you can simplify and use the Interlocked class and have this take care of making it an atomic operation:
public class Stock
{
private static int FaceValue {get; set;}
Public void UpdateStock()
{
//only a single property to update now
Interlocked.Increment(FaceValue);
}
// method that reads the two properties
public int[] GetStockQuote()
{
var currVal = FaceValue;
return new int[] { currVal, currVal * 100 };
}
}
See Interlocked on MSDN.

Are private member variables really thread safe in asp.net code behind class?

I am seeing a random exception "Collection was modified; enumeration may not execute" - InvalidOperationException.
The exception points to foreach line in the code snippet below, I know this happens when a collection is modified while enumerating.
However in my scenario, I don't see a real chance of it happening - UNLESS private member is not thread safe.. I may be wrong, but this where I need help to understand and figure out.
Here is how my code looks
I have code behind class which has a private collection like
private Dictionary<string, string> _someDictionary = SomeConstantClass.ConstantValue;
In the page prerender complete event, I am enumerating the dictionary
protected override void OnPagePreRenderComplete(object sender, EventArgs e){
_someDictionary["AnotherKey"] = "Another value";
foreach(var dataValuePair in _SomeDictionary){
//Do some operation
}
}
I also have a public property which can modify this collection, but it set in the ascx file like
<tc: UserControlA runat="server" id="abc" CustomProperty="true" />
and here is its implementation,
public bool CustomProperty{
set{
if (value)
_someDictionary["CustomProperty"] = "Custom Value";
}
}
It certainly modified my member variable collection - But as per my understanding this property should be fired and done in the Control Init itself.
So, I still dont see a scenario where the collection is modified during the pre render complete event.
Any idea what could cause the exception to occur??
other notes: the page certainly has many update panels though this specific usercontrol does not do anything fancy and does not even have postback scenario.
From the log I see that the issue is happening in HTTP GET request to the page.
Moreover: Suggest me a way (if any) to reproduce this.
For my friends who were interested to know the SomeConstantClass.ConstantValue, here it is
class SomeConstantClass{
public static Dictionary<string, string> ConstantValue = new Dictionary<string, string> {
{"ABCD", "EFGH"},
{"HIJK", "LMNO"}
};
}
If you are returning the same instance from SomeConstantClass.ConstantValue then multiple pages will have the private member variable pointing to the same object. This will lead to the object being changed on the init of one page while its being iterated on the OnPagePreRenderComplete of another page.
Make sure that you return a new instance of the dictionary in each access to SomeConstantClass.ConstantValue. Example:
public static Dictionary<string, string> ConstantValue
{
get
{
return new Dictionary<string, string>
{
{"ABCD", "EFGH"},
{"HIJK", "LMNO"}
};
}
}
This way each page will have it own dictionary object to work with. This is the quick solution, you could refactor the logic so that you don't need to have to create a new dictionary for each page.
Basically private member variables are only thread safe if they reference an object that is private to that page and no one else knows about that object or the object itself is designed to be thread-safe. Encapsulating access to a non thread-safe static object through a private member will not make it thread safe.
As long as you know you're not sharing the dictionary across requests (or you are purposely doing that) you can skip trying to figure out why, and just use a Concurrent Dictionary which is thread safe. Just because a Dictionary is private doesn't make it thread safe.

What is the best way to implement a property=value collection

I've written a wrapper class around a 3rd party library that requires properties to be set by calling a Config method and passing a string formatted as "Property=Value"
I'd like to pass all the properties in a single call and process them iteratively.
I've considered the following:
creating a property/value class and then creating a List of these
objects
building a string of multiple "Property=Value" separating them
with a token (maybe "|")
Using a hash table
All of these would work (and I'm thinking of using option 1) but is there a better way?
A bit more detail about my query:
The finished class will be included in a library for re-use in other applications. Whilst I don't currently see threading as a problem at the moment (our apps tend to just have a UI thread and a worker thread) it could become an issue in the future.
Garbage collection will not be an issue.
Access to arbitrary indices of the data source is not currently an issue.
Optimization is not currently an issue but clearly define the key/value pairs is important.
As you've already pointed out, any of the proposed solutions will accomplish the task as you've described it. What this means is that the only rational way to choose a particular method is to define your requirements:
Does your code need to support multiple threads accessing the data source simultaneously? If so, using a ConcurrentDictionary, as Yahia suggested, makes sense. Otherwise, there's no reason to incur the additional overhead and complexity of using a concurrent data structure.
Are you working in an environment where garbage collection is a problem (for example, an XNA game)? If so, any suggestion involving the concatenation of strings is going to be problematic.
Do you need O(1) access to arbitrary indices of the data source? If so, your third approach makes sense. On the other hand, if all you're doing is iterating over the collection, there's no reason to incur the additional overhead of inserting into a hashtable; use a List<KeyValuePair<String, String>> instead.
On the other hand, you may not be working in an environment where the optimization described above is necessary; the ability to clearly define the key/value pairs programatically may be more important to you. In which case using a Dictionary is a better choice.
You can't make an informed decision as to how to implement a feature without completely defining what the feature needs to do, and since you haven't done that, any answer given here will necessarily be incomplete.
Given your clarifications, I would personally suggest the following:
Avoid making your Config() method thread-safe by default, as per the MSDN guidelines:
By default, class libraries should not be thread safe. Adding locks to create thread-safe code decreases performance, increases lock contention, and creates the possibility for deadlock bugs to occur.
If thread safety becomes important later, make it the caller's responsibility.
Given that you don't have special performance requirements, stick with a dictionary to allow key/value pairs to be easily defined and read.
For simplicity's sake, and to avoid generating lots of unnecessary strings doing concatenations, just pass the dictionary in directly and iterate over it.
Consider the following example:
var configData = new Dictionary<String, String>
configData["key1"] = "value1";
configData["key2"] = "value2";
myLibraryObject.Config(configData);
And the implementation of Config:
public void Config(Dictionary<String, String> values)
{
foreach(var kvp in values)
{
var configString = String.Format("{0}={1}", kvp.Key, kvp.Value);
// do whatever
}
}
You could use Dictionary<string,string>, the items are then of type KeyValuePair<string,string> (this correpsonds to your first idea)
You can then use myDict.Select(kvp=>string.Format("{0}={1}",kvp.Key,kvp.Value)) to get a list of strings with the needed formatting
Use for example a ConcurrentDictionary<string,string> - it is thread-safe and really fast since most operations are implemented lock-free...
You could make a helper class that uses reflection to turn any class into a Property=Value collection
public static class PropertyValueHelper
{
public static IEnumerable<string> GetPropertyValues(object source)
{
Type t = source.GetType();
foreach (var property in t.GetProperties())
{
object value = property.GetValue(source, null);
if (value != null)
{
yield return property.Name + "=" + value.ToString();
}
else
{
yield return property.Name + "=";
}
}
}
}
You would need to add extra logic to handle enumerations, indexed properties, etc.

C# Dictionary with ReaderWriterLockSlim

I'm very new to multi-threading and for some reason this class is giving me more trouble than it should.
I am setting up a dictionary in the ASP.net cache - It will be frequently queried for individual objects, enumerated occasionally, and written extremely infrequently. I'll note that the dictionary data is almost never changed, I'm planning on letting it expire daily with a callback to rebuild from the database when it leaves the cache.
I believe that the enumeration and access by keys are safe so long as the dictionary isn't being written. I'm thinking a ReaderWriterLockSlim based wrapper class is the way to go but I'm fuzzy on a few points.
If I use Lock I believe that I can either lock on a token or the actual object I'm protecting. I don't see how to do something similar using the ReaderWriter Lock. Am I correct in thinking that multiple instances of my wrapper will not lock properly as the ReaderWriterLocks are out of each other's scope?
What is the best practice for writing a wrapper like this? Building it as a static almost seems redundant as the primary object is being maintained by the cache. Singleton's seem to be frowned upon, and I'm concerned about the above mentioned scoping issues for individual instances.
I've seen a few implementations of similar wrappers around but I haven't been able to answer these questions. I just want to make sure that I have a firm grasp on what I'm doing rather than cutting & pasting my way through. Thank you very much for your help!
**Edit: Hopefully this is a clearer summary of what I'm trying to find out- **
1. Am I correct in thinking that the lock does not affect the underlying data and is scoped like any other variable?
As an example lets say i have the following -
MyWrapperClass
{
ReaderWriterLockSlim lck = new ReaderWriterLockSlim();
Do stuff with this lock on the underlying cached dictionary object...
}
MyWrapperClass wrapA = new MyWrapperClass();
MyWrapperClass wrapB = new MyWrapperClass();
Am I right in thinking that the wrapA lock and wrapB lock won't interact, And that if wrapA & wrapB both attempt operations it will be unsafe?
2. If this is the case what is the best practice way to "share" the lock data?
This is an Asp.net app - there will be multiple pages that need to access the data which is why i'm doing this in the first place. What is the best practice for ensuring that the various wrappers are using the same lock? Should my wrapper be a static or singleton that all threads are using, if not what is the more elegant alternative?
You have multiple dictionary objects in the Cache, and you want each one locked independently. The "best" way is to just use a simple class that does it for you.
public class ReadWriteDictionary<K,V>
{
private readonly Dictionary<K,V> dict = new Dictionary<K,V>();
private readonly ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();
public V Get(K key)
{
return ReadLock(() => dict[key]);
}
public void Set(K key, V value)
{
WriteLock(() => dict.Add(key, value));
}
public IEnumerable<KeyValuePair<K, V>> GetPairs()
{
return ReadLock(() => dict.ToList());
}
private V2 ReadLock<V2>(Func<V2> func)
{
rwLock.EnterReadLock();
try
{
return func();
}
finally
{
rwLock.ExitReadLock();
}
}
private void WriteLock(Action action)
{
rwLock.EnterWriteLock();
try
{
action();
}
finally
{
rwLock.ExitWriteLock();
}
}
}
Cache["somekey"] = new ReadWriteDictionary<string,int>();
There is also a more complete example on the help page of ReaderWriterLockSlim on MSDN. It wouldn't be hard to make it generic.
edit To answer your new questions -
1.) You are correct wrapA and wrapB will not interact. They both have their own instance of ReaderWriterLockSlim.
2.) If you need a shared lock amongst all your wrapper classes, then it must be static.
ConcurrentDictionary does everything you want and then some. Part of System.Concurrent.Collections
The standard way to lock is: object lck = new object(); ... lock(lck) { ... } in this instance the object lck represents the lock.
ReadWriterLockSlim isn't much different, its just in this case the actual ReadWriterLockSlim class represents the actual lock, so everywhere you would have used lck you now use your ReadWriterLockSlim.
ReadWriterLockSlim lck = new ReadWriterLockSlim();
...
lck.EnterReadLock();
try
{
...
}
finally
{
lck.ExitReadLock();
}

Categories

Resources