views:

60

answers:

3

I have a C# class which has a dictionary inside it. The class listens asynchronously to messages that, upon arrival and processing, alter the data in the dictionary.

What is the "correct" way for an app that uses an instance of this class to iterate through the data in the dictionary? Do I have to wrap it into another class and implement some sort of enumerator? Is it appropriate to add something like Pause and Resume methods to the class that the app can call when it wants to iterate over the data?

+1  A: 

Well, you should lock on the dictionary any time you are iterating over it or modifying it.

Like so:

var d = new Dictionary<int, string>();

lock (d)
{
    d.Add(1, "Q");
}

lock (d)
{
    foreach (var p in d)
    {
        Console.WriteLine(p.Key + " => " + p.Value);
    }
}

If your iteration is going to do something substantial, you should copy before iterating.

IList<KeyValuePair<int, string>> d2;

lock (d)
{
    d2 = d.ToList();
}

foreach (var p in d2)
{
    Console.WriteLine(p.Key + " => " + p.Value);
}
John Gietzen
yeah, I'm doing that now while prototyping, but I don't like the dictionary object being public...so I could create a couple of public methods to wrap up obtaining and releasing a lock, but I was wondering if there was a more standard pattern for this situation.
highprotein
A: 

Another option is the copy the data before iterating.

Joel Lucsy
A: 

There are really 2 options for how the client can iterate over the data

  1. It can acquire the same synchronization lock that is used to protect the data when being updated asnchrously.
  2. The class in charge of the data can return an independent copy of the data to the caller
JaredPar