I want to safely iterate(not get a collection was changed during iteration) through an array that can be changed by another thread. What's the best way I can do it?
Make a copy? I guess it depends on whether you want your iteration to be a 'snapshot in time' or if you want to see the changes 'live'. The latter can get pretty dicey.
What do you mean by "safely"? Do you mind seeing a mixture of old and new values? If so, you can just iterate using foreach
. (This is for two reasons: firstly, arrays don't have an internal "version number" like List<T>
does, so the iterator can't detect that the array has changed. Secondly, using foreach
on a type known to be an array in C# causes the compiler to use the length and indexer anyway, rather than using an iterator.)
If you want to get a snapshot, you basically need to take a copy of the array and iterate over that.
EDIT: I was assuming you wanted concurrency. (I'm not sure why I assumed that.) I agree with the other answers that locking is an alternative - but you need to lock around the whole iteration, e.g.
lock (someLock)
{
foreach (var x in array)
{
// Stuff
}
}
and likewise in the writing thread:
lock (someLock)
{
array[0] = "foo";
}
(You could lock on the array itself, but I generally prefer to have private locks.)
You probably want to use syncronized access. You can lock the array for the time you need to parse it and the time you add/remove items.
You could use lock/unlock (http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.80).aspx
For ultra safeness, you could lock all access to the array while you are iterating through it. Its the only way to ensure that the array you are iterating through is fully up to date..