views:

587

answers:

3

MSDN points out that mutating access to the .NET Dictionary<K,V> type is not thread safe. Is there a standard thread safe version?

Note: "No there is not" is a valid answer if it is true. In that cases (and it seem to be) I'll go off and do the lock thing.


Almost Duplicate

What’s the best way of implementing a thread-safe Dictionary in .NET? (Not exact because I want a standard type, not something I implement my self)

+1  A: 

In addition to the answer of the duplicate question, you might want to take a look at this implementation that uses ReaderWriterSlim. ReaderWriterSlim ought to infact offer some performance benefits over simple locking (which effectively uses Monitor) - definitely take a look.

Noldorin
Not a standard type.
BCS
@BCS: I thought the answer should be obvious from the duplicate that there is no standard type. This is the best you're going to get.
Noldorin
I'll take that that answerer to this one is "No" but that the answerer the the almost duplicate is code how can they be actual duplicates?
BCS
@BCS: See my comment on the question. And anyway, you have your answer now.
Noldorin
+3  A: 

There isn't. Consider this code, where each method/property was thread safe

if (!SFdict.Contains(key))
{
  SFdict.[key] = value;
}

athough each action could be threadsafe, the block of code has a race condition, b/c there are two method calls and two different critical sections. The only way to do it is by hand

lock(lck)
{
 if (!dict.Contains(key))
 {
   dict.[key] = value;
 }
}
Scott Weinstein
An AddOrReturnOld method would work for that. Also your example is a good argument for why there should be standard type that gets these things right
BCS
+2  A: 

While Hashtable is not generic, is is thread-safe so long as you use it right (one writer, multiple readers, no enumeration).

Thread Safety

To support one or more writers, all operations on the Hashtable must be done through the wrapper returned by the Synchronized method.

Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.

It is different than a dictionary though -- it will return null, not throw a KeyNotFoundException if you try to get a value that doesn't exist (so storing null values can be problematic). It's a very useful collection if you know you'll never have more than one thread trying to add a new key, and can deal with the null issue.

Jonathan
I could have many writers so no joy. :(
BCS