I have a class that maintains a private Dictionary instance that caches some data.
The class writes to the dictionary from multiple threads using a ReaderWriterLockSlim.
I want to expose the dictionary’s values outside the class.
What is a thread-safe way of doing that?
Right now, I have the following:
public ReadOnlyCollection<MyClass> Values() {
using (sync.ReadLock())
return new ReadOnlyCollection<MyClass>(cache.Values.ToArray());
}
Is there a way to do this without copying the collection many times?
I’m using .Net 3.5 (not 4.0)
EDIT: I personally believe the below code is technically answering your question correctly (as in, it provides a way to enumerate over the values in a collection without creating a copy). Some developers far more reputable than I strongly advise against this approach, for reasons they have explained in their edits/comments. In short: This is apparently a bad idea. Therefore I’m leaving the answer but suggesting you not use it.
Unless I’m missing something, I believe you could expose your values as an
IEnumerable<MyClass>without needing to copy values by using theyieldkeyword:Be aware, however (and I’m guessing you already knew this), that this approach provides lazy evaluation, which means that the
Valuesproperty as implemented above can not be treated as providing a snapshot.In other words… well, take a look at this code (I am of course guessing as to some of the details of this class of yours):
So if it’s a requirement that this
Valuesproperty be equivalent to a snapshot of what is incacheat the time the property is accessed, then you’re going to have to make a copy.(begin 280Z28): The following is an example of how someone unfamiliar with the “C# way of doing things” could lock the code:
(end 280Z28)