Identify InvalidOperationException "Collection was modified; enumeration operation may not execute." - c#

I've got a good old InvalidOperationException being thrown with the standard message
Collection was modified; enumeration operation may not execute.
The problem is, the enumerator isn't modifying itself, for example:
private TRoute _copyRoute(TRoute route)
{
TRoute tempRoute = new TRoute();
tempRoute.Initialize(route.Resource);
foreach (TVisit visit in route)
{
tempRoute.Add(visit);
}
tempRoute.EndLocation = route.EndLocation;
return tempRoute;
}
My code is multi-threaded (circa 12-15 threads for this example) and each thread is supposed to be working on its own deep clone of a route. Obviously something is going wrong somewhere, but, my question is how do I track this down with so many threads? Reducing the number significantly stops the problem manifesting itself.
In this case my route instance is an IList so I can play around with adding things to the interface. Underneath it has it's own List implementation.
EDIT
Just to add, I could ToArray() or ToList() this and maybe ignore the problem here but I don't really want to do that, I want to locate the cause. For example:
If I change it to the following:
private TRoute _copyRoute(TRoute route)
{
TRoute tempRoute = new TRoute();
tempRoute.Initialize(route.Resource);
foreach (TVisit visit in route.ToList())
{
tempRoute.Add(visit);
}
tempRoute.EndLocation = route.EndLocation;
return tempRoute;
}
Then I fail on this Assert, because a chance has occurred just before ToList()... I need to try and find out where that change is occuring
TRoute tempRoute1 = CopyRoute(route1);
TRoute tempRoute2 = CopyRoute(route2);
Debug.Assert(tempRoute1.Count == route1.Count);

Here's something you can use to wrap your IList<T> - it checks that it's on the right thread on each write operation. Of course, it would still be unsafe to be iterating over this on one thread while writing on another, but I assume that's not the problem. (You could always call CheckThread on all operations, not just the writing ones.)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
class ThreadAffineList<T> : IList<T>
{
private readonly Thread expectedThread;
private readonly IList<T> list;
public ThreadAffineList(IList<T> list)
{
this.list = list;
this.expectedThread = Thread.CurrentThread;
}
private void CheckThread()
{
if (Thread.CurrentThread != expectedThread)
{
throw new InvalidOperationException("Incorrect thread");
}
}
// Modification methods: delegate after checking thread
public T this[int index]
{
get { return list[index]; }
set
{
CheckThread();
list[index] = value;
}
}
public void Add(T item)
{
CheckThread();
list.Add(item);
}
public void Clear()
{
CheckThread();
list.Clear();
}
public void Insert(int index, T item)
{
CheckThread();
list.Insert(index, item);
}
public bool Remove(T item)
{
CheckThread();
return list.Remove(item);
}
public void RemoveAt(int index)
{
CheckThread();
list.RemoveAt(index);
}
// Read-only members
public int Count { get { return list.Count; } }
public bool IsReadOnly { get { return list.IsReadOnly; } }
public IEnumerator<T> GetEnumerator()
{
return list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public bool Contains(T item)
{
return list.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
list.CopyTo(array, arrayIndex);
}
public int IndexOf(T item)
{
return list.IndexOf(item);
}
}

Assuming you're in control of Add(TVisit)/Remove(TVisit) of TRoute underlying collection:
Extend your TRoute.IEnumerator<TVisit> GetEnumerator() to set an AutoResetEvent or Mutex
Extend your Add(TVisit)/Remove(TVisit) methods to wait for event/mutex with zero timeout
if(!autoReseEvent.WaitOne(0)) throw new MyException();
Catch MyExpcetion and you'll get the stack trace and change origin.
UPDATE:
The issue with this approach is when to release event/mutex. You'll probably have to decorate your enumerator with a new class like below:
public IEnumerator<TVisit> GetEnumerator()
{
IEnumerator<TVisit> originEnum = // get it somehow from underlying collection
IEnumerator<TVisit> evenlope = new DisposableEvenlope<TVisit>(originEnum);
evenlope.Disposed += new EventHandler(/* do your magic and reset event/mutex here */);
return evenlope;
}
And the evelope itself:
public class DisposableEvenlope<T> : IEnumerator<T>
{
private IEnumerator<T> _privateEnum;
public event System.EventHandler Disposed;
public DisposableEvenlope(IEnumerator<T> privateEnum)
{
_privateEnum = privateEnum;
}
public T Current
{
get { return _privateEnum.Current; }
}
public void Dispose()
{
Disposed(this, new System.EventArgs());
}
object IEnumerator.Current
{
get { return _privateEnum.Current; }
}
public bool MoveNext()
{
return _privateEnum.MoveNext();
}
public void Reset()
{
_privateEnum.Reset();
}
}

The problem is obviously not in the code you have written as you are not modifying the collection while enumerating.
Somehow one of two things is happening:
Your route is somehow not a deep clone and some thread is modyfying the same collection you are passing to the pasted logic (that should be easy to track is it is a coding issue somewhere, not some nasty race condition).
Your exception is being raised precisely in the cloning logic and not in the code you have pasted.
Try implementing some locking mechanism while deep cloning your collection and see if that solves the issue.

Since you are aware that mutiple thread can touch route, prevent any touch on route with a lock(), and always in a lock() convert route.ToArray() and then use that array for loop. This since you probably feel some performance drawbacks if you lock() the entire loop. To catch who is really touching the collection, you can derive it and track the thread id in a local member variable in the add/remove elements.

Related

Memoize result of the same function called inside different delegates

I have a function that takes a list of Func<bool> each with an attached value. It iterates the list and returns the attached value if a delegate returns true. Some of these delegates call the same function with the same parameters how do I best memoize the result of such calls within the scope of the TryFindValue method?
The return value of the functions may change between calls to TryFindValue, but they will not change while iterating the list. I would like to avoid generating garbage (boxing/unboxing by casting to object for example). Ideally, I would only have to use the space for memoized values in the scope of TryFindValue and not for the entire lifetime of each delegate for example, but I do not know if that is possible.
public class SomeClass
{
public bool TryFindValue(List<CondValue> list, out int value)
{
for (int i = 0; i < list.Count; i++)
{
var condValue = list[i];
if (condValue.cond())
{
value = condValue.value;
return true;
}
}
value = default(int);
return false;
}
}
public class SomeOtherClass
{
private List<CondValue> list;
public SomeOtherClass()
{
list = new List<CondValue>();
// SomeMethod(3) will be calculated twice
list.Add(new CondValue(() => SomeMethod(3) > SomeOtherMethod(), 42));
list.Add(new CondValue(() => SomeMethod(3) < SomeThirdMethod(), 35));
}
private float SomeMethod(int value)
{
// Implementation... (uses some internal or global state)
}
private int SomeOtherMethod()
{
// Implementation... (uses some internal or global state)
}
private int SomeThirdMethod()
{
// Implementation... (uses some internal or global state)
}
}
public struct CondValue
{
public Func<bool> cond;
public int value;
public CondValue(Func<bool> func, int value)
{
this.func = func;
this.value = value;
}
}
If you turn CondValue.cond into an expression tree instead of a Func then maybe you could make some complicated solution. I have no experience doing so and I wouldn't suggest venturing out on that adventure. Apart from that I don't see a good solution to only keep it cached/memorized within the lifetime of a single call to TryFindValue.
I would rather ask you:
Is there any good reason you have the current setup?
It seems like an unnecessarily complicated setup. Since you've only shown a very abstract example it's difficult to suggest a better alternative.
Would e.g. SomeMethod(3) not always return the same value?
You could wrap that method in some caching logic (e.g. with help from PostSharp). But if it doesn't consistently return the same value, you'd have to clear that cache when necessary, which makes it harder to maintain.
Instead of having individual conditions that return true or false with an attached value you could just return the value or null. How does that help? For the following solution, I am assuming that the delegates in the list that call the same function are added to the list together in the same function (here in the constructor SomeOtherClass). From there you could batch together delegates that call the same functions with the same parameters in an if-else if code block and manually "memoize" the result of the function at the top of the delegate.
Delegates that call the same functions with the same parameters smells like they are related in this if-else if relationship anyway. I have added SomeFourthMethod to show how to still compactly add a single conditional individually.
If you have suggestions to improve the details of this solution (using something else than nullable, etc.) then feel free to suggest it in a comment.
If all the conditions are always independent and just happen to sometimes call the same function, then this solution might not be appropriate. Otherwise, it is the simplest most effective solution I can think of.
public class SomeClass
{
public bool TryFindValue(List<Func<int?>> list, out int value)
{
for (int i = 0; i < list.Count; i++)
{
var func = list[i];
int? ret = func();
if (ret.HasValue)
{
value = ret.Value;
return true;
}
}
value = default(int);
return false;
}
}
public class SomeOtherClass
{
private List<Func<int?>> list;
public SomeOtherClass()
{
list = new List<Func<int?>>();
Add(() =>
{
float memoized = SomeMethod(3);
if (memoized > SomeOtherMethod())
return 42;
else if (memoized < SomeThirdMethod())
return 35;
return null;
});
Add(() => SomeFourthMethod() > 4, 72);
}
private void Add(Func<int?> snippet)
{
list.Add(snippet);
}
private void Add(Func<bool> cond, int value)
{
list.Add(() =>
{
if (cond())
return value;
return null;
});
}
private float SomeMethod(int value)
{
// Implementation... (uses some internal or global state)
}
private int SomeOtherMethod()
{
// Implementation... (uses some internal or global state)
}
private int SomeThirdMethod()
{
// Implementation... (uses some internal or global state)
}
private int SomeFourthMethod()
{
// Implementation... (uses some internal or global state)
}
}

Multi-threading in Enumerator

I am using C# and I have an enumerator and I am reading the data inside the enumerator sequentially.
This is a third party library object and does not support Parallel.Foreach
while(enumerator.Next())
{
var item = enumerator.Read();
ProcessItem(item);
}
ProcessItem(Item item)
{
// Is lock required here
if(item.prop == "somevalue")
this._list.Add(item);
}
I want to achieve multithreading here while reading the content.
while(enumerator.Next())
{
// This code should run in a multi-threaded way
var item = enumerator.Read();
// ProcessItem method puts these items on a class level list property
// Is there any Lock required?
ProcessItem(item);
}
I am new to multithreading. Please share any code samples which satisfies the above requirement.
Yes, some locking required. you can achieve it using lock or using a concurrent collection type.
using lock:
ProcessItem(Item item)
{
if(item.prop == "somevalue")
{
lock(_list)
{
_list.Add(item);
}
}
}
Edit: based on detail you provided, you can wrap the enumerator from external lib using your own enumerator like below so you can use Parallel.ForEach on it:
We assume the enumerator you got is something like MockEnumerator, we wrap it in a normal IEnumerator, and IEnumerable so we are able to use Parallel.ForEach to read in parallel.
class Program
{
class Item
{
public int SomeProperty { get; }
public Item(int prop)
{
SomeProperty = prop;
}
}
class MockEnumerator
{
private Item[] _items = new Item[] { new Item(1), new Item(2) };
private int _position = 0;
public bool Next()
{
return _position++ < _items.Length;
}
public Item Read()
{
return _items[_position];
}
}
class EnumeratorWrapper : IEnumerator<Item>, IEnumerable<Item>
{
private readonly MockEnumerator _enumerator;
public EnumeratorWrapper(MockEnumerator enumerator)
{
this._enumerator = enumerator;
}
public Item Current => _enumerator.Read();
object IEnumerator.Current => Current;
public void Dispose()
{
}
public IEnumerator<Item> GetEnumerator()
{
throw new NotImplementedException();
}
public bool MoveNext()
{
return _enumerator.Next();
}
public void Reset()
{
}
IEnumerator IEnumerable.GetEnumerator()
{
return this;
}
}
private static List<Item> _list = new List<Item>();
static void Main(string[] args)
{
var enumerator = new EnumeratorWrapper(new MockEnumerator());
Parallel.ForEach(enumerator, item =>
{
if (item.SomeProperty == 1)//someval
{
lock (_list)
{
_list.Add(item);
}
}
});
}
}
This is a good example for task-based parallelization. Each processing of an item corresponds to a task. Hence, you can change the loop to the following:
var tasks = new List<Task<int>>();
while(enumerator.MoveNext())
{
var item = enumerator.Current;
Task<int> task = new Task<int>(() => ProcessItem(item));
task.Start();
tasks.Add(task);
}
foreach(Task<int> task in tasks)
{
int i = task.Result;
classList.Add(i);
}
Note that the synchronization on the classList is implicitly given by first spawning all tasks in the while loop and then merging the results in the foreach loop. The synchronization is specifically given by the access to Result which waits until the corresponding task is finished.

Possible to turn callback calls into IEnumerable

I'm writing a wrapper around a 3rd party library, and it has a method to scan the data it manages. The method takes a callback method that it calls for each item in the data that it finds.
e.g. The method is essentially: void Scan(Action<object> callback);
I want to wrap it and expose a method like IEnumerable<object> Scan();
Is this possible without resorting to a separate thread to do the actual scan and a buffer?
You can do this quite simply with Reactive:
class Program
{
static void Main(string[] args)
{
foreach (var x in CallBackToEnumerable<int>(Scan))
Console.WriteLine(x);
}
static IEnumerable<T> CallBackToEnumerable<T>(Action<Action<T>> functionReceivingCallback)
{
return Observable.Create<T>(o =>
{
// Schedule this onto another thread, otherwise it will block:
Scheduler.Later.Schedule(() =>
{
functionReceivingCallback(o.OnNext);
o.OnCompleted();
});
return () => { };
}).ToEnumerable();
}
public static void Scan(Action<int> act)
{
for (int i = 0; i < 100; i++)
{
// Delay to prove this is working asynchronously.
Thread.Sleep(100);
act(i);
}
}
}
Remember that this doesn't take care of things like cancellation, since the callback method doesn't really allow it. A proper solution would require work on the part of the external library.
You should investigate the Rx project — this allows an event source to be consumed as an IEnumerable.
I'm not sure if it allows vanilla callbacks to be presented as such (it's aimed at .NET events) but it would be worth a look as it should be possible to present a regular callback as an IObservable.
Here is a blocking enumerator (the Scan method needs to run in a separate thread)
public class MyEnumerator : IEnumerator<object>
{
private readonly Queue<object> _queue = new Queue<object>();
private ManualResetEvent _event = new ManualResetEvent(false);
public void Callback(object value)
{
lock (_queue)
{
_queue.Enqueue(value);
_event.Set();
}
}
public void Dispose()
{
}
public bool MoveNext()
{
_event.WaitOne();
lock (_queue)
{
Current = _queue.Dequeue();
if (_queue.Count == 0)
_event.Reset();
}
return true;
}
public void Reset()
{
_queue.Clear();
}
public object Current { get; private set; }
object IEnumerator.Current
{
get { return Current; }
}
}
static void Main(string[] args)
{
var enumerator = new MyEnumerator();
Scan(enumerator.Callback);
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
You could wrap it in a simple IEnumerable<Object>, but I would not recommend it. IEnumerable lists implies that you can run multiple enumerators on the same list, which you can't in this case.
How about this one:
IEnumerable<Object> Scan()
{
List<Object> objList = new List<Object>();
Action<Object> action = (obj) => { objList.Add(obj); };
Scan(action);
return objList;
}
Take a look at the yield keyword -- which will allow you to have a method that looks like an IEnumerable but which actually does processing for each return value.

Private inheritance in C#?

I'm new to C# and wondered if there is something like private inheritance in C# (like in C++) ?
My problem is as follows:
I want to implement a queue (name it SpecialQueue) with the following changes:
The queue has a maximum number of items that can be stored in it.
If the queue is full and you insert a new item, one item will be automatically poped out of the queue (the first item in the queue) and the new item will be inserted to the end of the queue.
Some methods (such as peek()) provided by queue should not be exposed to SpecialQueue's users.
In c++ I would private ihnerit from queue, expose only the methods I want to and change others to my will. But unfortunatley, all methods in queue don't have the "Override" modifier and I don't know how to achieve that in C#.
Any help?
Regards,
Dan
Use composition: include a usual Queue as a field in your SpecialQueue. Private inheritance is actually something very similar to composition.
See http://www.parashift.com/c++-faq-lite/private-inheritance.html#faq-24.3 for discussion.
Implementation could be something like that:
public class SpecialQueue<T>
{
private int capacity;
private Queue<T> storage;
public SpecialQueue(int capacity)
{
this.capacity = capacity;
storage = new Queue<T>();
// if (capacity <= 0) throw something
}
public void Push(T value)
{
if (storage.Count == capacity)
storage.Dequeue();
storage.Enqueue(value);
}
public T Pop()
{
if (storage.Count == 0)
throw new SomeException("Queue is empty");
return storage.Dequeue();
}
public int Count
{
get { return storage.Count; }
}
}
You need to add more functions/interfaces if you want SpecialQueue to support them. I would however not recommend to implement IEnumerable, because this would allow Peek (which you want to prohibit).
You could implement the same interfaces as a Queue (or Queue<T>), have a Queue as a backing field and expose those methods that you need to, which will simply wrap the calls to the backing field.
For example (have kept implementation of ICollection in line with Queue<T>)
public class SpecialQueue<T> : IEnumerable<T>, ICollection
{
private readonly Queue<T> _queue;
#region Constructors
public SpecialQueue()
{
_queue = new Queue<T>();
}
public SpecialQueue(int capacity)
{
_queue = new Queue<T>(capacity);
}
public SpecialQueue(IEnumerable<T> collection)
{
_queue = new Queue<T>(collection);
}
#endregion
#region Methods
// implement any methods that you want public here...
#endregion
#region Interface Implementations
public IEnumerator<T> GetEnumerator()
{
return _queue.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _queue.GetEnumerator();
}
public void CopyTo(Array array, int index)
{
((ICollection) _queue).CopyTo(array, index);
}
public int Count
{
get { return _queue.Count; }
}
public object SyncRoot
{
get { return ((ICollection) _queue).SyncRoot; }
}
public bool IsSynchronized
{
get { return ((ICollection) _queue).IsSynchronized; }
}
#endregion
}

Controlling access to an internal collection in c# - Pattern required

This is kind of hard to explain, I hope my English is sufficient:
I have a class "A" which should maintain a list of objects of class "B" (like a private List). A consumer of class "A" should be able to add items to the list. After the items are added to the list, the consumer should not be able to modify them again, left alone that he should not be able to temper with the list itself (add or remove items). But he should be able to enumerate the items in the list and get their values. Is there a pattern for it? How would you do that?
If the question is not clear enough, please let me know.
To prevent editing the list or its items you have to make them immutable, which means you have to return a new instance of an element on every request.
See Eric Lippert's excellent series of "Immutability in C#": http://blogs.msdn.com/ericlippert/archive/tags/Immutability/C_2300_/default.aspx (you have to scroll down a bit)
As many of these answers show, there are many ways to make the collection itself immutable.
It takes more effort to keep the members of the collection immutable. One possibility is to use a facade/proxy (sorry for the lack of brevity):
class B
{
public B(int data)
{
this.data = data;
}
public int data
{
get { return privateData; }
set { privateData = value; }
}
private int privateData;
}
class ProxyB
{
public ProxyB(B b)
{
actual = b;
}
public int data
{
get { return actual.data; }
}
private B actual;
}
class A : IEnumerable<ProxyB>
{
private List<B> bList = new List<B>();
class ProxyEnumerator : IEnumerator<ProxyB>
{
private IEnumerator<B> b_enum;
public ProxyEnumerator(IEnumerator<B> benum)
{
b_enum = benum;
}
public bool MoveNext()
{
return b_enum.MoveNext();
}
public ProxyB Current
{
get { return new ProxyB(b_enum.Current); }
}
Object IEnumerator.Current
{
get { return this.Current; }
}
public void Reset()
{
b_enum.Reset();
}
public void Dispose()
{
b_enum.Dispose();
}
}
public void AddB(B b) { bList.Add(b); }
public IEnumerator<ProxyB> GetEnumerator()
{
return new ProxyEnumerator(bList.GetEnumerator());
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
The downside of this solution is that the caller will be iterating over a collection of ProxyB objects, rather than the B objects they added.
EDIT: Added support for edition contexts. Caller can only add elements inside an edition context. You can aditionally enforce that only one edition context can be created for the lifetime of the instance.
Using encapsulation you can define any set of policies to access the inner private member. The following example is a basic implementation of your requirements:
namespace ConsoleApplication2
{
using System;
using System.Collections.Generic;
using System.Collections;
class B
{
}
interface IEditable
{
void StartEdit();
void StopEdit();
}
class EditContext<T> : IDisposable where T : IEditable
{
private T parent;
public EditContext(T parent)
{
parent.StartEdit();
this.parent = parent;
}
public void Dispose()
{
this.parent.StopEdit();
}
}
class A : IEnumerable<B>, IEditable
{
private List<B> _myList = new List<B>();
private bool editable;
public void Add(B o)
{
if (!editable)
{
throw new NotSupportedException();
}
_myList.Add(o);
}
public EditContext<A> ForEdition()
{
return new EditContext<A>(this);
}
public IEnumerator<B> GetEnumerator()
{
return _myList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public void StartEdit()
{
this.editable = true;
}
public void StopEdit()
{
this.editable = false;
}
}
class Program
{
static void Main(string[] args)
{
A a = new A();
using (EditContext<A> edit = a.ForEdition())
{
a.Add(new B());
a.Add(new B());
}
foreach (B o in a)
{
Console.WriteLine(o.GetType().ToString());
}
a.Add(new B());
Console.ReadLine();
}
}
}
You basically want to avoid to give away references to the class B items. That's why you should do a copy of the items.
I think this can be solved with the ToArray() method of a List object. You need to create a deep-copy of the list if you want to prevent changes.
Generally speaking: most of the times it is not worthwhile to do a copy to enforce good behaviour, especially when you also write the consumer.
public class MyList<T> : IEnumerable<T>{
public MyList(IEnumerable<T> source){
data.AddRange(source);
}
public IEnumerator<T> GetEnumerator(){
return data.Enumerator();
}
private List<T> data = new List<T>();
}
The downside is that a consumer can modify the items it gets from the Enumerator, a solution is to make deepcopy of the private List<T>.
It wasn't clear whether you also needed the B instances themselves to be immutable once added to the list. You can play a trick here by using a read-only interface for B, and only exposing these through the list.
internal class B : IB
{
private string someData;
public string SomeData
{
get { return someData; }
set { someData = value; }
}
}
public interface IB
{
string SomeData { get; }
}
The simplest that I can think of is return a readonly version of the underlying collection if editing is no longer allowed.
public IList ListOfB
{
get
{
if (_readOnlyMode)
return listOfB.AsReadOnly(); // also use ArrayList.ReadOnly(listOfB);
else
return listOfB;
}
}
Personally though, I would not expose the underlying list to the client and just provide methods for adding, removing, and enumerating the B instances.
Wow, there are some overly complex answers here for a simple problem.
Have a private List<T>
Have an public void AddItem(T item) method - whenever you decide to make that stop working, make it stop working. You could throw an exception or you could just make it fail silently. Depends on what you got going on over there.
Have a public T[] GetItems() method that does return _theList.ToArray()

Categories