Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why am I getting an exception InvalidOperationException?

I have written the following code which removes the selected value from the listBox. I also want to remove it from the Dictionary List and then update/write it to the text file so when I run the program again and load the text file it will be updated if not it will keep showing the removed item each time I run my application again.

private void listBox1_KeyDown(object sender, KeyEventArgs e)
        {
            string sb;
            if (e.KeyCode == Keys.Delete)
            {
                if (this.listBox1.SelectedIndex >= 0)
                {
                    string obj = this.listBox1.SelectedValue.ToString();
                    data.Remove(obj);
                    listBox1.DataSource = null;
                    listBox1.DataSource = data;
                    foreach (KeyValuePair<string, List<string>> kvp in LocalyKeyWords)
                    {
                        for (int i = 0; i < kvp.Value.Count(); i++)
                        {
                            sb = "Url: " + kvp.Key + " --- " + "Local KeyWord: " + kvp.Value[i] + Environment.NewLine;
                            LocalyKeyWords.Remove(kvp.Key);
                        }
                    }

                }
            }

        }

LocalyKeyWords is a Dictionary>

In this case it contain two items/keys I remove one and I see with a breakpoint that this one have been removed.

The question is if I need to remove the kvp.Key or to remove somehow the item I removed from the listBox wich is the one I want to remove from the LocalyKeywords and it's the obj variable since im doing:

data.Remove(obj);

So maybe I need to remove obj also from the localyKeyWords ?

The excpetion the error im getting is after it's removing the item from the LocalyKeyWords an click continue on this line:

foreach (KeyValuePair<string, List<string>> kvp in LocalyKeyWords)

Im getting the error:

Collection was modified; enumeration operation may not execute

System.InvalidOperationException was unhandled
  HResult=-2146233079
  Message=Collection was modified; enumeration operation may not execute.
  Source=mscorlib
  StackTrace:
       at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
       at System.Collections.Generic.Dictionary`2.Enumerator.MoveNext()
       at GatherLinks.Form1.listBox1_KeyDown(Object sender, KeyEventArgs e) in d:\C-Sharp\GatherLinks\GatherLinks\GatherLinks\Form1.cs:line 959
       at System.Windows.Forms.Control.OnKeyDown(KeyEventArgs e)
       at System.Windows.Forms.Control.ProcessKeyEventArgs(Message& m)
       at System.Windows.Forms.Control.ProcessKeyMessage(Message& m)
       at System.Windows.Forms.Control.WmKeyChar(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ListBox.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(IntPtr 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 GatherLinks.Program.Main() in d:\C-Sharp\GatherLinks\GatherLinks\GatherLinks\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly 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.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
like image 525
user2065612 Avatar asked Feb 24 '13 22:02

user2065612


People also ask

Should I throw InvalidOperationException?

The InvalidOperationException exception should not be thrown for errors caused by invalid arguments. For invalid argument errors, throw ArgumentException or one of its derived types, such as ArgumentNullException or ArgumentOutOfRangeException.

What can cause an application to throw an exception?

Exceptions can be thrown because of a fault in your code or in code that you call (such as a shared library), unavailable operating system resources, unexpected conditions that the runtime encounters (such as code that can't be verified), and so on.

When should you throw an ArgumentException?

ArgumentException is thrown when a method is invoked and at least one of the passed arguments does not meet the parameter specification of the called method. The ParamName property identifies the invalid argument.


2 Answers

You are removing items from LocalyKeyWords while in the midst of iterating over it; that is not allowed, as the exception message says.

I 'm not sure what the big picture is here, but a localized solution would be to make a temporary copy of LocalyKeyWords and iterate over that. You can then modify the "source" collection without any trouble.

Example:

foreach (var kvp in LocalyKeyWords.ToList())  // .ToList() makes a temp copy
like image 106
Jon Avatar answered Nov 16 '22 01:11

Jon


You can't modify the IEnumerable collection inside of foreach.

You can create a copy of the dictionary and loop through it modifing the original one.

like image 40
VladL Avatar answered Nov 16 '22 00:11

VladL