views:

100

answers:

3

I am looking at Skeet's AtomicEnumerable but I'm not sure how to integrate it into my current IEnumerable exmaple below (http://msmvps.com/blogs/jon_skeet/archive/2009/10/23/iterating-atomically.aspx)

Basically I want to foreach my blahs type in a thread-safe way.

thanks

so .. foreach on multiple threads ... giving correct order

Blahs b = new Blahs();

foreach (string s in b) { }

public sealed class Blahs :  IEnumerable<string>
{
    private readonly IList<string> _data = new List<string>() { "blah1", "blah2", "blah3" };

    public IEnumerator<string> GetEnumerator()
    {
        return _data.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
+2  A: 

Do you mean you want each thread to see the same sequence, or that between all the threads, each item should be seen exactly once?

Are you able to use .NET 4? If so, Parallel Extensions (e.g. Parallel.ForEach) is your friend - it's likely to be much safer than anything I could come up with :)

EDIT: If you want to just iterate over the list completely in each thread, and nothing is going to be modifying the list, it will be thread-safe already. If you do need to modify the list, then you should create a copy of the list and iterate over that instead.

Jon Skeet
I need each thread to see the same sequence. Unfortunately I'm stuck on 3.5 for the time being
DayOne
@DayOne: See my edit.
Jon Skeet
A: 

If you just need each thread to see the same sequence then your code might be thread-safe as it is.

Your _data list is private, so it can only be modified from within the Blahs class itself (assuming that you don't expose it elsewhere).

The List<T> class is safe for multiple concurrent readers, which means that all you need to do is ensure that your Blahs class doesn't modify the collection while it is being enumerated.

Your example code is thread-safe as it is, but I'm sure your real code isn't actually this simple.

LukeH
+1  A: 

The linked code solves a different problem, you are trying to do something much more difficult. You have to do nothing special with the iterators, as long as the collection isn't being modified while it is being iterated. Guaranteeing this can be difficult, you'll have to keep a lock that prevents any thread from adding items. Not great for concurrency.

If that's not suitable then you'll have to make a copy of the collection to provide the guarantee. No bed of roses either, a thread will now by definition always see a stale version of the collection.

Hans Passant