Solved

Not sure how to resolve error: ""Collection was modified; enumeration operation may not execute."

Posted on 2008-10-02
15
913 Views
Last Modified: 2012-06-27
Hi

As mentioned above, I get the error:
"Collection was modified; enumeration operation may not execute."

The code that is causing this is below.

I checked up on previous thread with the same issue and understand that it is when you do a foreach loop through a collection, and then try to modify the contents of that collection within the loop.

But in my code, as seen below, nothing is modifying the messageOutDictionary Collection.
The only bit of code that touches it is:
Regex MyRE = new Regex(messageOutDictionary[tKeyInDictionary]);

This is not modifying the collection as far as I know, so what could be causing the issue??

Thanks
Paolo
private String SetMessageOut(String template, Dictionary<String, String> messageOutDictionary)
		{
			String message_OUT = template;
			String tSearchValue;
			String tKeyInDictionary;
			String tKeyNew;
			String[] tSearchDuplicateKeyName = new String[1];
						
			foreach (String key in messageOutDictionary.Keys)
			{
				tKeyInDictionary = key;
				tKeyNew = key;
				
				//Handle Duplicates
				tSearchDuplicateKeyName = key.ToString().Split('|');
				if (tSearchDuplicateKeyName.Length > 1)
				{
					tKeyNew = tSearchDuplicateKeyName[0];
				}
 
				//Value to Replace
				tSearchValue = "{" + tKeyNew.ToString() + "}";
				
				//Replacement
				Regex MyRE = new Regex(messageOutDictionary[tKeyInDictionary]);
				string res = MyRE.Replace(message_OUT, tKeyNew, 1);
			}
 
			return message_OUT;
		}

Open in new window

0
Comment
Question by:djcheeky
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
  • 2
  • +1
15 Comments
 
LVL 22

Accepted Solution

by:
p_davis earned 45 total points
ID: 22624151
you can't modify records in a foreach loop -- you will have to do something like a regular for loop
0
 

Author Comment

by:djcheeky
ID: 22624203
A regular for loop is not possible as the keys aren't sequential. They are text keys.
0
 

Author Comment

by:djcheeky
ID: 22624211
Plus, there are no "records" so to speak. It's just norma lvalues.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 22

Expert Comment

by:p_davis
ID: 22624355
why does it matter if they are sequential -- if they aren't, they wouldn't be in a foreach loop either -

what are you trying to do. -- it looks like you are trying to replace key values -- the comment says handle duplicates but duplicate keys aren't allowed in dictionaries, so i am a little confused.
0
 

Author Comment

by:djcheeky
ID: 22624428
Hi,

No - it's not duplicates in the Dictionary, don't worry about that code.
The issue remains that I get the error? You can see that the dictionary data (be it values or keys) isn't modified.

Thanks

0
 
LVL 22

Expert Comment

by:p_davis
ID: 22624467
sorry about that i didn't read you question closely enough -- specifically, what line does it error out on?
0
 

Author Comment

by:djcheeky
ID: 22624636
foreach (String keyOUT in DictionaryOUT.Keys)

0
 
LVL 22

Expert Comment

by:p_davis
ID: 22624911
what about trying
foreach(KeyValuePair<String,String> pair in DictionaryOUt)
{

}
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 22625343
Hi djcheeky;

I looked at the code and could not see why you are getting the error. I then tested your code and it ran without issue. Can you give some test data for the collection  messageOutDictionary so that I can test with like data as you.

Fernando
0
 
LVL 26

Expert Comment

by:Anurag Thakur
ID: 22626759
tried your code and it compiles and runs perfectly
the collection is not modified at all.
can you please provide us with some test data as requested by Fernando too, it migt be helpful to us to try to debug and find the solution to the exception thats coming
0
 

Author Comment

by:djcheeky
ID: 22631616
Hi all and thanks for the response.

>>Fernando / Ragi

You are both in fact correct. After actually trapping the error down further it seems that error is happening with the code below.

This in fact DOES modify records in a Dictionary, so I will attempt to work around this, change the code, and see what happens and get back to you.

Thanks
private Dictionary<String, String> SetMessageOutDictionaryValues(Dictionary<String, String> DictionaryIN, Dictionary<String, String> DictionaryOUT)
		{
			foreach (String keyOUT in DictionaryOUT.Keys)
			{
				if (DictionaryIN.ContainsKey(keyOUT))
				{
					DictionaryOUT[keyOUT] = DictionaryIN[keyOUT];
				}
				else
				{
					DictionaryOUT[keyOUT] = "";
				}
			}
			return DictionaryOUT;
		}

Open in new window

0
 

Author Comment

by:djcheeky
ID: 22631709
Hmmm.... OK, now I'm a bit stumped.

I have modified the method so that the Dictionary Collection in the "foreach" loop is not modified, yet I still get the error. The code is attached below.

As you can see - I am looping through the DictionaryOUT dictionary, but modifying the messageOutDictionaryValues dictionary, yet still get the error??

The Data in the Dictionary I am using is (and please note that the value null illustrated is actually a String, not the null operator):

[MessageReferenceNumber][null]
[MessageType][null]
[MessageVersionNumber][null]
[MessageReleaseNumber][null]
[ControllingAgency][null]
[AssociationAssignedCode][null]
[DocumentMessageName][null]
[DocumentMessageId][null]
[DateTimePeriodQualifier][null]
[DateTimePeriod][null]
[DateTimePeriodFormatQualifier][null]
[PlaceLocationQualifier][null]
[PlaceLocationIdentification][null]
[CodeListQualifier][null]
[CodeListResponsibleAgency][null]
[ProcessingIndicator][null]
[CodeListQualifier_1][null]
[CodeListResponsibleAgency_1][null]
[PartyQualifier][null]
[PartyIdentificationDetails][null]
[DateTimePeriodQualifier_1][null]
[DateTimePeriod_1][null]
[DateTimePeriodFormatQualifier_1][null]

Thanks
Paolo
private Dictionary<String, String> SetMessageOutDictionaryValues(Dictionary<String, String> DictionaryIN, Dictionary<String, String> DictionaryOUT)
		{
			Dictionary<String, String> messageOutDictionaryValues = new Dictionary<String, String>();
			messageOutDictionaryValues = DictionaryOUT;
 
			foreach (String keyOUT in DictionaryOUT.Keys)
			{
				if (DictionaryIN.ContainsKey(keyOUT))
				{
					messageOutDictionaryValues[keyOUT] = DictionaryIN[keyOUT];
				}
				else
				{
					messageOutDictionaryValues[keyOUT] = "";
				}
			}
			return messageOutDictionaryValues;
		}

Open in new window

0
 
LVL 26

Assisted Solution

by:Anurag Thakur
Anurag Thakur earned 45 total points
ID: 22631757
if the requirement is to modify the key value in the dictionary then use a for loop instead of the for each loop.
if you need to remove objects from the dictionary then do the reverse loop (loop from top (count) to bottom (0))
0
 

Author Comment

by:djcheeky
ID: 22631936
Hi - Ok, I managed to find a way to get around it, using a normal for loop.

What was required for this example to work though was also creating an array of the keys, which I could then reference using the for loops index.

Thanks

private Dictionary<String, String> SetMessageOutDictionaryValues(Dictionary<String, String> DictionaryIN, Dictionary<String, String> DictionaryOUT)
		{
			String[] tKeyValues = new String[DictionaryOUT.Keys.Count];
			int j = 0;
			foreach (String keyOUT in DictionaryOUT.Keys)
			{
				tKeyValues[j] = keyOUT;
				j++;
			}
			for (int i = 0; i < tKeyValues.Length; i++)
			{
				if (DictionaryIN.ContainsKey(tKeyValues[i]))
				{
					DictionaryOUT[tKeyValues[i]] = DictionaryIN[tKeyValues[i]];
				}
				else
				{
					DictionaryOUT[tKeyValues[i]] = "no match";
				}
			}
			/*
			foreach (String keyOUT in DictionaryOUT.Keys)
			{
				if (DictionaryIN.ContainsKey(keyOUT))
				{
					DictionaryOUT[keyOUT] = DictionaryIN[keyOUT];
				}
				else
				{
					DictionaryOUT[keyOUT] = "";
				}
			}
			 */ 
			return DictionaryOUT;
		}

Open in new window

0
 
LVL 22

Expert Comment

by:p_davis
ID: 22632915
The first comment i made suggested using a regular for loop.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
using sqldatareader to populate cells in Excel-syntax 6 35
VS2010 Build fails to install 14 102
Dictionary and array of [N] size - performance tuned 12 52
Example code 13 42
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question