Collection was modified; enumeration operation may not execute.

Answered Collection was modified; enumeration operation may not execute.

  • Wednesday, January 06, 2010 1:27 PM
     
      Has Code

    When adding points to our chart we get the following exception:

    "An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.DataVisualization.dll

    Additional information: Collection was modified; enumeration operation may not execute."

    Visual Studio points at the following line (this doesn't help much since it is at the entry point of the application):

    Application.Run(new LacteaMainWindow());

    This is the stack trace (we don't understand much but perhaps someone else does):

    System.InvalidOperationException was unhandled
      Message="Collection was modified; enumeration operation may not execute."
      Source="mscorlib"
      StackTrace:
           at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
           at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
           at System.Collections.Generic.List`1.Enumerator.MoveNext()
           at System.Windows.Forms.DataVisualization.Charting.ChartTypes.FastLineChart.Paint(ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw)
           at System.Windows.Forms.DataVisualization.Charting.ChartArea.Paint(ChartGraphics graph)
           at System.Windows.Forms.DataVisualization.Charting.ChartPicture.Paint(Graphics graph, Boolean paintTopLevelElementOnly)
           at System.Windows.Forms.DataVisualization.Charting.Chart.OnPaint(PaintEventArgs e)
           at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)
           at System.Windows.Forms.Control.WmPaint(Message& m)
           at System.Windows.Forms.Control.WndProc(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.Run(Form mainForm)
           at Lactea.Program.Main() in C:\School\CDT310\project\trunk\source\Lactea\Lactea\Program.cs:line 18
           at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException:

    {System.Collections.ListDictionaryInternal}

    I have read other threads about this exception but we don't remove points from a collection nor use foreach anywhere which seemed to be the problems.

    Any ideas? This happens when we enable SuppressExceptions too. We are a couple of days away from our project presentation and this is a major problem. We can try to provide more info if you need it.

All Replies

  • Tuesday, February 02, 2010 9:29 AM
     
     

    Anyone? It bothers us that we are unable to find a solution for this thus not satisfying our customer. Any ideas are welcomed.

  • Thursday, February 04, 2010 6:23 PM
     
     
    Ok we managed to "fix" the initial problem by creating a UserControl, inherit from a Chart control and override OnPaint. In OnPaint we catch the exception and use the code found here: http://www.sturmnet.org/blog/2005/03/23/red-x

    Now only one minor "problem" remains. The chart is only redrawn after we minimize the application and then go back to normal window state. We tried to use Invalidate() and Update() but it doesn't work. Is there a way to achieve the minimize and normal state switching without actually doing it?
  • Monday, February 22, 2010 10:29 PM
     
     
    I believe this may be happening if you are updating or modifying your chart from a different thread than it was created on.  Is this true?  If so, you may need to invoke the update code on that thread.  Lookup Invoke and BeginInvoke in the MSDN.  You may be able to use the Invoke function in the chart itself (if it has one) or use the containing form's Invoke.
  • Tuesday, February 23, 2010 1:08 AM
     
     
    Thanks for replying.

    I checked the return value of InvokeRequired before the line where we add a point and it returned false which means we are adding on the correct thread.

    Also, shouldn't we always receive an exception when we add a point if this was the problem? It only happens sometimes and it happens more often on some computers.
  • Tuesday, February 23, 2010 1:46 PM
     
     Answered
    You wouldn't always receive an exception.  Many times that's exactly what happens... you just get an occassional exception.  I thought I'd throw the possibility out there, since I had a similar problem with a third-party control.  But if InvokeRequired is returning false, then you are correct to assume that you do not need to Invoke.  Good luck.
  • Thursday, April 05, 2012 2:48 PM
     
     

    This is usually a problem when you enumerate over a collection with a foreach loop, and then modify the element in the collection inside the loop. One thing to look at is whether you have a foreach loop somewhere further up the call stack.

    The solution that I've used in the past is instead of:
    foreach (Object object in ObjectCollection)

    Do this instead:

    foreach(Object object in ObjectCollection.Select(x => x))

  • Thursday, April 05, 2012 3:03 PM
     
     
    I think in your case the more likely possibility is that your collection is not thread safe. One thread is making changes to the collection, then in another thread you are trying to enumerate. Doing something as simple as:

    object = (From o In objects
                         Where o.id = someID
                         Select o).FirstOrDefault

    Would throw an exception. So you have to make your collection thread safe, either make it immutable or have some type of queue that manages read/write access to the collection.
  • Monday, April 30, 2012 12:32 AM
     
     

    hi Jim

    that exactly the solution for this problem

    I dont Give you 10 or 30 or 1000 stars for Rating I give you Google stars

    that is very Helpful

    Tanx so so so mach

  • Monday, April 30, 2012 12:41 AM
     
     

    ok

    try with this

    public delegate void DelegateStandardPattern(); // just try to write it
            void charting()     // method to  add points
            
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new DelegateStandardPattern(this.charting));
                    return;
                }
                lock (Data.Err_OutPut)
                {

                     chart1.Series["Series1"].Points.AddXY(h++, you_data_value);// for example h is globe variable
                 

    }}

    try to put charting method with  in any thread

    start the thread "Start()"

    and if the god willing  will run exactly like you want

    this Idea is picked from " Jim Gruenbacher" replay


    • Edited by belsambi Monday, April 30, 2012 12:41 AM
    •