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)

Community
  • 1
  • 1
BCS
  • 75,627
  • 68
  • 187
  • 294
  • There's definitely no standard-type. The BCL doesn't provide one for you because there's many different ways to implement thread-safety (using ReaderWriterSlim as I suggest, or a simple lock, which may be good enough). I'm still of the opinion this is an exact duplicate. – Noldorin May 08 '09 at 23:08

4 Answers4

3

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;
   }
}
Chris Marasti-Georg
  • 34,091
  • 15
  • 92
  • 137
Scott Weinstein
  • 18,890
  • 14
  • 78
  • 115
  • 3
    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 May 08 '09 at 22:57
2

While Hashtable is not generic, it 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<K, V> 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.

FishBasketGordo
  • 22,904
  • 4
  • 58
  • 91
Jonathan Rupp
  • 15,522
  • 5
  • 45
  • 61
2

.NET 4.0 now has a ConcurrentDictionary<K,T> class that seems to do what you want. Also in .NET 4.5

Crypth
  • 1,576
  • 18
  • 32
Metro
  • 1,464
  • 14
  • 24
1

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
  • 144,213
  • 56
  • 264
  • 302
  • @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 May 08 '09 at 23:04
  • 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 May 08 '09 at 23:12
  • @BCS: See my comment on the question. And anyway, you have your answer now. – Noldorin May 09 '09 at 08:46