I have a few library utilities which make things a little simpler.
public static RequestUow Uow
{
get { return ContextItemsHelper.Get<RequestUow>("Uow"); }
set { ContextItemsHelper.Set<RequestUow>("Uow", value); }
}
And in ContextItemsHelper
public static T Get<T>(string key)
{
Guard.NullOrEmpty(key, "key");
object obj = Items[key];
return obj.IsNotNull() ? (T)obj : default(T);
}
static IDictionary Items { get { return HttpContextHelper.Current.Items; } }
This works fine but i now want to check if the property uow is null, if it is set a new RequestUow and return it.
The examples I've seen involve setting your own member variable, however i'm wondering if this is likely to be threadsafe.
Anyone got any advice or solutions to offer?
Make Items a ConcurrentDictionary and use it's AddOrUpdate method. As the collection itself is thread safe, you won't have to care about it.
It would also be better if yourGet changed to something like this:
public static T Get<T>(string key)
{
Guard.NullOrEmpty(key, "key");
return Items.GetOrAdd( key, (key) => default(T) );
}
This way the defaults are added at first try and just returned if they are called again.
use pattern Double checked locking pattern
As long as the dictionary doesn't mutate (e.g. no updates), access it is fully threadsafe without any additional measures (*).
Note that it doesn't help to have threadsafe getter/setters for the dictionary if the items contained aren't threadsafe themselves. The safest bet is to use immutable items in the dictionary; if your RequestUow objects are mutable, then you need to make them (and everything else that might be retrieved using this dictionary) threadsafe as well.
*: See for instance this PDF for information on thread-safe collections in .NET. Page 18 clarifies that read-only access does not need additional measured for thread safety.
Related
I have an error, some of the users have reported recently, but i couldn't catch.
According to research i think it can be solved with changing Dictionary to ConcurrentDictionary. The question is how can i catch the error? What is the best way to use ConcurrentDictionary for adding (TryAdd or AddorUpdate)?
Edit: codes in references.
private static Dictionary<string, SportsFacility> _selectedFacilities = new Dictionary<string, SportsFacility>();
public static SportsFacility SelectedFacility
{
get
{
return _selectedFacilities.ContainsKey(HttpContext.Current.Session.SessionID) ? _selectedFacilities[HttpContext.Current.Session.SessionID] : null;
}
set
{
if (_selectedFacilities.ContainsKey(HttpContext.Current.Session.SessionID))
{
_selectedFacilities[HttpContext.Current.Session.SessionID] = value;
}
else
{
_selectedFacilities.Add(HttpContext.Current.Session.SessionID, value);
}
}
}
Never minding the reason for working with the session id like this (there are certainly better ways of doing this), here is a slight improvement to your code:
private static readonly object _selectedFacilitiesLocker=new object();
private static Dictionary<string, SportsFacility> _selectedFacilities = new Dictionary<string, SportsFacility>();
private static bool TryGetSelectedFacility(string key, out SportsFacility facility)
{
// Since you are in a web environment and are using statics, you must lock this index whenever you use it
lock(_selectedFacilitiesLocker)
{
return _selectedFacilities.TryGetValue(key, out facility);
}
}
private static void UpdateSelectedFacility(string key, SportsFacility facility)
{
// Since you are in a web environment and are using statics, you must lock this index whenever you use it
lock(_selectedFacilitiesLocker)
{
_selectedFacilities[key] = facility;
}
}
public static SportsFacility SelectedFacility
{
get
{
SportsFacility facility;
if(!TryGetSelectedFacility(HttpContext.Current.Session.SessionID, out facility))
return null;
else
return facility;
}
set
{
UpdateSelectedFacility(HttpContext.Current.Session.SessionID, value);
}
}
Using a static index ("_selectedFacilities") like you do in your code spells trouble in a multi threaded environment, like a web server. If you want a design like this (without going into the reasons for why you shouldn't), you must add a lock around it whenever you use it. Otherwise you'll get all kinds of strange bugs as soon as you're in production. It may seem to work while you're happily testing yourself but life isn't that easy, unfortunately.
This exception caused by using dictionary object from multiple threads without syncronizing. You can solve it by syncronizing access to dictionary object with lock (as #KEkegren suggested) or with ReaderWriterLockSlim
In addition to syncronizing manually, as you said, you can use ConcurrentDictionary without using locks. It is supported on .NET Framework 4 and above.
All operations on ConcurrentDictionary are atomic, meaning all methods are thread safe and you do not need to syncronize access.
However you should not use the same way as Dictionary. I mean, you should not check for key existence and after that add a new value. Instead you should use AddOrUpdate in your case because it makes what you are trying to do in a single atomic operation.
Rather than criticizing a particular approach, provide an answer that shows a better solution.
This does the same thing you are doing with a static dictionary using session variables.
public static SportsFacility SelectedFacility
{
get
{
return (Session["SelectedFacility"] as SportsFacility);
}
set
{
Session["SelectedFacility"] = value;
}
}
Good luck!
I have a memory cached object-cache, said cache can hold multiple types, and i want to add a lock on said {T} whenever given {T} is accessed.
My implementation:
readonly static IDictionary<Type, List<object>> _cache = new ConcurrentDictionary<Type, List<object>>();
private static List<object> FindTypeInCache(Type type)
{
List<object> list;
if (_cache.TryGetValue(type, out list))
{
return list;
}
else
{
_cache[type] = new List<object>();
}
return new List<object>();
}
public static T FindFirstBy<T>(Func<T, bool> predicate) where T : class
{
// Is this a valid lock locking only _cache[T] ? And not _cache as whole?
lock (_cache[typeof(T)])
{
return FindTypeInCache(typeof(T)).Cast<T>().Where(predicate).FirstOrDefault();
}
}
public static bool AddOrUpdate<T>(Func<T, bool> predicate, T entity) where T : class
{
lock (_cache[typeof(T)])
{
// Find Type cache.
List<object> list = FindTypeInCache(typeof(T));
// Look for old entity.
var e = list.Cast<T>().Where(predicate).FirstOrDefault();
// If no old record exists no problem we treat this as if its a new record.
if (e != null)
{
// Old record found removing it.
list.Remove(e);
}
// Regardless if object existed or not we add it to our Cache.
list.Add(entity);
_cache[typeof(T)] = list;
}
}
Is my implementation correct only locking down _cache[T] and not entire _cache as a whole when accessed?
There's a lot of things weird (or outright wrong) with your code.
First, you're using a ConcurrentDictionary, but you're not using it as a concurrent dictionary. For example, to initialize the list, you'd use the GetOrAddMethod:
private static List<object> FindTypeInCache(Type type)
{
return _cache.GetOrAdd(type, () => new List<object>());
}
Simple and thread-safe :)
Second, you're locking on _cache[type] - but even when there's no such type in the cache. This means a KeyNotFoundException.
Third, the only code you're protecting with the lock is the reading. But that quite likely isn't enough - at the very least, you need to also protect the writing with the same lock (especially tricky given the point above), and depending on your actual usage of the return value, the return value's mutations (and if it is indeed mutable, any reads of that mutable value as well).
In other words, you've only managed to protect the code that doesn't actually need protecting (if you use the correct method to update the dictionary)! The extra lock around the Where etc. might help slightly, but it certainly doesn't make the List access safe.
All that said, maybe there's a better solution anyway. You're using the cache using generic methods. Why not make the cache itself generic? This way, you'll avoid using a dictionary in the first place, because each of the generic types you're storing in the dictionary will get their own type - it also means you can initialize the List<T> in a static constructor safely. Any locking can than also be safely applied to all access to a specific generic cache rather than the "aggregate" cache you have now.
I have a Visual Studio 2008 C# .NET 3.5 project where I want to have a thread-safe pool of Foo objects.
public class FooPool
{
private object pool_lock_ = new object();
private Dictionary<int, Foo> foo_pool_ = new Dictionary<int, Foo>();
// ...
public void Add(Foo f)
{
lock (pool_lock_)
{
foo_pool_.Add(SomeFooDescriminator, f);
}
}
public Foo this[string key]
{
get { return foo_pool_[key]; }
set { lock (pool_lock_) { foo_pool_[key] = value; } }
}
public IEnumerable<Foo> Foos
{
get
{
lock (pool_lock_)
{
// is this thread-safe?
return foo_pool_.Select(x => x.Value);
}
}
}
}
Is the public IEnumerable<Foo> Foos { get; } function thread-safe? Or, do I need to clone the result and return a new list?
No, it isn't.
If another thread adds to the dictionary while your caller enumerates that, you'll get an error.
Instead, you can do:
lock (pool_lock_) {
return foo_pool.Values.ToList();
}
Is the IEnumerable<Foo> Foos { get; } function thread-safe?
No.
Or, do I need to clone the result and return a new list?
No, because that's not right either. A threadsafe method that gives the wrong answer is not very useful.
If you lock and make a copy then the thing you are returning is a snapshot of the past. The collection could be changed to be completely different the moment the lock is released. If you make this threadsafe by making a copy then you are now handing a bag full of lies to your caller.
When you are dealing with single-threaded code, a reasonable model is that everything is staying the same unless you take specific measures to change a thing. That is not a reasonable model in multi-threaded code. In multi-threaded code, you should assume the opposite: everything is constantly changing unless you take specific measures (such as a lock) to ensure that things are not changing. What is the good of handing out a sequence of Foos that describe the state of the world in the distant past, hundreds of nanoseconds ago? The entire world could be different in that amount of time.
It is not thread safe. You need to return ToList():
return foo_pool_.Select(x => x.Value).ToList();
Careful of deferred execution!
The fact is the actual code runs after the lock has exited.
// Don't do this
lock (pool_lock_)
{
return foo_pool_.Select(x => x.Value); // This only prepares the statement, does not run it
}
You may want to consider a SynchronizedCollection,
SynchronizedCollection Class
Provides a thread-safe collection that contains objects of a type specified by the generic parameter as elements.
http://msdn.microsoft.com/en-us/library/ms668265.aspx
If you'll lock on every read access you'll end with very bad performance. And in suggestions to use toList you'll also allocate memory every time.
If you using .NET 4 just use ConcurrentDictionary class from new thread safe collections. They will provide very fast (lock free) mechanisms for accessing data from multiple threads.
http://msdn.microsoft.com/en-us/library/dd997305.aspx
If you are using old .NET version I would suggest you to use for cycle with count variable instead of foreach it will work if you only add elements without removing them (as in your example)
I've a class that contains a static collection to store the logged-in users in an ASP.NET MVC application. I just want to know about the below code is thread-safe or not. Do I need to lock the code whenever I add or remove item to the onlineUsers collection.
public class OnlineUsers
{
private static List<string> onlineUsers = new List<string>();
public static EventHandler<string> OnUserAdded;
public static EventHandler<string> OnUserRemoved;
private OnlineUsers()
{
}
static OnlineUsers()
{
}
public static int NoOfOnlineUsers
{
get
{
return onlineUsers.Count;
}
}
public static List<string> GetUsers()
{
return onlineUsers;
}
public static void AddUser(string userName)
{
if (!onlineUsers.Contains(userName))
{
onlineUsers.Add(userName);
if (OnUserAdded != null)
OnUserAdded(null, userName);
}
}
public static void RemoveUser(string userName)
{
if (onlineUsers.Contains(userName))
{
onlineUsers.Remove(userName);
if (OnUserRemoved != null)
OnUserRemoved(null, userName);
}
}
}
That is absolutely not thread safe. Any time 2 threads are doing something (very common in a web application), chaos is possible - exceptions, or silent data loss.
Yes you need some kind of synchronization such as lock; and static is usually a very bad idea for data storage, IMO (unless treated very carefully and limited to things like configuration data).
Also - static events are notorious for a good way to keep object graphs alive unexpectedly. Treat those with caution too; if you subscribe once only, fine - but don't subscribe etc per request.
Also - it isn't just locking the operations, since this line:
return onlineUsers;
returns your list, now unprotected. all access to an item must be synchronized. Personally I'd return a copy, i.e.
lock(syncObj) {
return onlineUsers.ToArray();
}
Finally, returning a .Count from such can be confusing - as it is not guaranteed to still be Count at any point. It is informational at that point in time only.
Yes, you need to lock the onlineUsers to make that code threadsafe.
A few notes:
Using a HashSet<string> instead of the List<string> may be a good idea, since it is much more efficient for operations like this (Contains and Remove especially). This does not change anything on the locking requirements though.
You can declare a class as "static" if it has only static members.
Yes you do need to lock your code.
object padlock = new object
public bool Contains(T item)
{
lock (padlock)
{
return items.Contains(item);
}
}
Yes. You need to lock the collection before you read or write to the collection, since multiple users are potentially being added from different threadpool workers. You should probably also do it on the count as well, though if you're not concerned with 100% accuracy that may not be an issue.
As per Lucero's answer, you need to lock onlineUsers. Also be careful what will clients of your class do with the onlineUsers returned from GetUsers(). I suggest you change your interface - for example use IEnumerable<string> GetUsers() and make sure the lock is used in its implementation. Something like this:
public static IEnumerable<string> GetUsers() {
lock (...) {
foreach (var element in onlineUsers)
yield return element;
// We need foreach, just "return onlineUsers" would release the lock too early!
}
}
Note that this implementation can expose you to deadlocks if users try to call some other method of OnlineUsers that uses lock, while still iterating over the result of GetUsers().
That code it is not thread-safe per se.
I will not make any suggestions relative to your "design", since you didn't ask any. I'll assume you found good reasons for those static members and exposing your list's contents as you did.
However, if you want to make your code thread-safe, you should basically use a lock object to lock on, and wrap the contents of your methods with a lock statement:
private readonly object syncObject = new object();
void SomeMethod()
{
lock (this.syncObject)
{
// Work with your list here
}
}
Beware that those events being raised have the potential to hold the lock for an extended period of time, depending on what the delegates do.
You could omit the lock from the NoOfOnlineUsers property while declaring your list as volatile. However, if you want the Count value to persist for as long as you are using it at a certain moment, use a lock there, as well.
As others suggested here, exposing your list directly, even with a lock, will still pose a "threat" on it's contents. I would go with returning a copy (and that should fit most purposes) as Mark Gravell advised.
Now, since you said you are using this in an ASP.NET environment, it is worth saying that all local and member variables, as well as their member variables, if any, are thread safe.
I have a producer / consumer queue, except that there are specific types of objects. So not just any consumer can consume an added object. I don't want to make a specific queue for each type, as there are too many. (It sort of stretches the definition of producer/consumer, but I'm not sure what the correct term is.)
Is there such a thing as an EventWaitHandle which allows pulses with a parameter? e.g. myHandle.Set(AddedType = "foo"). Right now I'm using Monitor.Wait and then each consumer checks to see if the pulse was actually intended for them, but that seems kind of pointless.
A pseduocode version of what I have now:
class MyWorker {
public string MyType {get; set;}
public static Dictionary<string, MyInfo> data;
public static void DoWork(){
while(true){
if(Monitor.Wait(data, timeout)){
if (data.ContainsKey(MyType)){
// OK, do work
}
}
}
}
}
As you can see, I might get pulses when other stuff is added to the dict. I only care when MyType is added to the dict. Is there a way to do that? It's not a huge deal, but, for example, I have to manually handle timeouts now, because each get of the lock could succeed within the timeout, but MyType is never added to the dict within timeout.
This is an interesting question. It sounds like the key to the solution is a blocking variant of a priority queue. Java has the PriorityBlockingQueue, but unfortunately the equivalent for the .NET BCL is nonexistent. Once you have one, however, the implementation is easy.
class MyWorker
{
public string MyType {get; set;}
public static PriorityBlockingQueue<string, MyInfo> data;
public static void DoWork()
{
while(true)
{
MyInfo value;
if (data.TryTake(MyType, timeout, out value))
{
// OK, do work
}
}
}
}
Implementing a PriorityBlockingQueue is not terribly difficult. Following the same pattern as BlockingCollection by utilizing Add and Take style methods I came up with the following code.
public class PriorityBlockingQueue<TKey, TValue>
{
private SortedDictionary<TKey, TValue> m_Dictionary = new SortedDictionary<TKey,TValue>();
public void Add(TKey key, TValue value)
{
lock (m_Dictionary)
{
m_Dictionary.Add(key, value);
Monitor.Pulse(m_Dictionary);
}
}
public TValue Take(TKey key)
{
TValue value;
TryTake(key, TimeSpan.FromTicks(long.MaxValue), out value);
return value;
}
public bool TryTake(TKey key, TimeSpan timeout, out TValue value)
{
value = default(TValue);
DateTime initial = DateTime.UtcNow;
lock (m_Dictionary)
{
while (!m_Dictionary.TryGetValue(key, out value))
{
if (m_Dictionary.Count > 0) Monitor.Pulse(m_Dictionary); // Important!
TimeSpan span = timeout - (DateTime.UtcNow - initial);
if (!Monitor.Wait(m_Dictionary, span))
{
return false;
}
}
m_Dictionary.Remove(key);
return true;
}
}
}
This was a quick implementation and it has a couple of problems. First, I have not tested it at all. Second, it uses a red-black tree (via SortedDictionary) as the underlying data structure. That means the TryTake method will have O(log(n)) complexity. Priority queues typically have O(1) removal complexity. The typically data structure of choice for priority queues is a heap, but I find that skip lists are actually better in practice for several reasons. Neither of these exist in the .NET BCL which is why I used a SortedDictionary instead despite its inferior performance in this scenario.
I should point out here that this does not actually solve the pointless Wait/Pulse behavior. It is simply encapsulated in the PriorityBlockingQueue class. But, at the very least this will certainly cleanup the core part of your code.
It did not appear like your code handled multiple objects per key, but that would be easy to add by using a Queue<MyInfo> instead of a plain old MyInfo when adding to the dictionary.
It seems like you want to combine producer/consumer queue with an Observer pattern - generic consumer thread or threads reads from the queue, and then passes the event to the required code. In this instance you would not actually signal the Observer but just call it when the consumer thread identifies who is interested in a given work item.
Observer pattern in .Net is typically implemented using C# events. You would just need to call the event handler for the object and one or more observers would get invoked through it. The target code would first have to register itself with the observed object by adding itself to the event for notification on arrival of work.