2011-05-30 13 views
26

Possible Duplicate:
Collection was modified; enumeration operation may not executeसी # संग्रह संशोधित किया गया था; गणन किए गए कार्य पूरे नहीं हो सकता है

नमस्ते,

मैं एक परियोजना आकलन कार्यक्रम बनाने के हूँ और कर रहा हूँ निम्न त्रुटि हो रही है: सी # संग्रह संशोधित किया गया था; गणना ऑपरेशन निष्पादित नहीं हो सकता है।

यह इस का उपयोग कर से संबंधित है: मैं initally इस के साथ विश्व स्तर पर diciontary घोषित:

private void getFirstEstimation() 
{ 
    List<int> array = new List<int>(); 

    string strConnection = ConfigurationSettings.AppSettings["ConnectionString"]; 
    MySqlConnection connection = new MySqlConnection(strConnection); 
    MySqlCommand command = connection.CreateCommand(); 
    MySqlDataReader reader; 
    command.CommandText = "SELECT idprojects FROM `test`.`projects` WHERE application_layers = " + applicationTiers; 
    connection.Open(); 

    reader = command.ExecuteReader(); 
    while (reader.Read()) 
    { 
     array.Add(Convert.ToInt32(reader["idprojects"].ToString())); 
    } 
    foreach (int i in array) 
    { 
     rankings[i] = 15; 
    } 
    connection.Close(); 
} 

मैं एक के लिए इसे कहते:

Dictionary<int, int> rankings = new Dictionary<int, int>(); 

अगला विधि इस शब्दकोश युक्त निम्नलिखित करता है दूसरी बार यहां:

private void getSecondEstimation() 
{ 
    Dictionary<int, string> sqltext = new Dictionary<int, string>(); 
    Dictionary<int, int> valueForSql = new Dictionary<int, int>(); 
    Dictionary<int, int> weightings = new Dictionary<int, int>(); 
    sqltext.Add(1, "project_type"); 
    valueForSql.Add(1, projectType); 
    weightings.Add(1, 10); 
    sqltext.Add(2, "application_domain"); 
    valueForSql.Add(2, applicationDomain); 
    weightings.Add(2, 8); 
    sqltext.Add(3, "organisation_size"); 
    valueForSql.Add(3, organizationSize); 
    weightings.Add(3, 8); 
    sqltext.Add(4, "no_of_locations"); 
    valueForSql.Add(4, noOfLocations); 
    weightings.Add(4, 7); 
    sqltext.Add(5, "development_process"); 
    valueForSql.Add(5, developmentProcess); 
    weightings.Add(5, 6); 
    sqltext.Add(6, "rules_engine"); 
    valueForSql.Add(6, rulesEngine); 
    weightings.Add(6, 5); 
    sqltext.Add(7, "middleware"); 
    valueForSql.Add(7, middleware); 
    weightings.Add(7, 4); 
    sqltext.Add(8, "location_of_development"); 
    valueForSql.Add(8, locationOfDevelopment); 
    weightings.Add(8, 3); 
    sqltext.Add(9, "programming_language"); 
    valueForSql.Add(9, programmingLanguage); 
    weightings.Add(9, 3); 
    sqltext.Add(10, "development_environment"); 
    valueForSql.Add(10, developmentEnvironment); 
    weightings.Add(10, 3); 
    sqltext.Add(11, "backend"); 
    valueForSql.Add(11, backend); 
    weightings.Add(11, 3); 
    sqltext.Add(12, "webserver"); 
    valueForSql.Add(12, webServer); 
    weightings.Add(12, 3); 

    List<int> array = new List<int>(); 

    string strConnection = ConfigurationSettings.AppSettings["ConnectionString"]; 
    MySqlConnection connection = new MySqlConnection(strConnection); 
    MySqlCommand command = connection.CreateCommand(); 
    MySqlDataReader reader; 

    for (int i = 1; i <= 12; i++) 
    { 
     command.CommandText = "SELECT idprojects FROM `test`.`projects` WHERE " + sqltext[i] + " = " + valueForSql[i]; 
     connection.Open(); 
     //int testInt; 
     reader = command.ExecuteReader(); 
     while (reader.Read()) 
     { 
      array.Add(Convert.ToInt32(reader["idprojects"].ToString())); 
     } 
     foreach (int a in array) 
     { 
      if (!rankings.ContainsKey(a)) 
      { 
       rankings[a] = 0; 
      } 
      rankings[a] = rankings[a] + weightings[i]; 
     } 
     connection.Close(); 
    }  
} 

समस्या इस पर उत्पन्न होती है कोड के क्षेत्र:

private void getThirdEstimation() 
{ 
    ArrayList tempModuleHolder; 

    string strConnection = ConfigurationSettings.AppSettings["ConnectionString"]; 
    MySqlConnection connection = new MySqlConnection(strConnection); 
    MySqlCommand command = connection.CreateCommand(); 
    MySqlDataReader reader; 
    int similarModules; 

    foreach (KeyValuePair<int, int> kvp in rankings) 
    { 
     similarModules = 0; 
     tempModuleHolder = new ArrayList(); 
     command.CommandText = "SELECT id_modules FROM `test`.`modules_in_project` WHERE id_project = " + kvp.Key; 
     connection.Open(); 

     reader = command.ExecuteReader(); 
     while (reader.Read()) 
     { 
      tempModuleHolder.Add(Convert.ToInt32(reader["id_modules"].ToString())); 
     } 

     foreach (int i in tempModuleHolder) 
     { 
      if(modules.Contains(i)) 
      { 
       similarModules++; 
      } 
     } 
     if((double)(similarModules/modules.Count)>0.6) 
     { 
      //kvp.Value = kvp.Value + 4; 
      rankings[kvp.Key] = rankings[kvp.Key] + 4; 
     } 
     connection.Close(); 
    } 
} 

जहां समस्या झूठ बहुत सराहना की जाएगी

+0

बीटीडब्ल्यू, विषय से बाहर, आपका MySQL कनेक्शन और MySqlDataReader क्लास निपटान() विधि के लिए IDISposable लागू नहीं करता है, ताकि आप कनेक्शन और पाठक के आसपास ब्लॉक का उपयोग कर उपयोग कर सकें? –

+1

@ydobonmai: 'MySQL कनेक्शन' और 'MySqlDataReader' शायद MySQL डेटाबेस के साथ काम करने के लिए' MySQL.Data.MySqlClient' कक्षाओं को संदर्भित करता है। इसलिए, वे 'आईडीस्पोजेबल' लागू करते हैं और उनके उपयोग को 'उपयोग' ब्लॉक में लपेटा जाना चाहिए। – jason

उत्तर

80

किसी भी संग्रह है कि आप foreach के साथ खत्म हो गया पुनरावृति के साथ कोई मदद यात्रा के दौरान संशोधित नहीं किया जा सकता है।

तो जब आप रैंकिंग पर एक foreach चला रहे हैं, तो आप इसके तत्वों को संशोधित नहीं कर सकते हैं, नए जोड़ सकते हैं या किसी को हटा सकते हैं।

+22

हालांकि आप संग्रह की एक प्रति के माध्यम से पाश कर सकते हैं। उदाहरण के लिए लूप instanciation पर 'संग्रह.ToArray() '। संग्रह के "प्रतिलिपि" को बदलने के दौरान यह आपको लूप में अपने वास्तविक संग्रह को संशोधित करने देगा। स्रोत http://stackoverflow.com/questions/604831/collection-was-modified-enumeration-operation-may-not-execute –

+3

+1 डॉन: ToArray() इसे ठीक करता है। @Roy को +1 भी। – Mukus

+0

मुझे आश्चर्य है कि यह बग अभी तक क्यों तय नहीं किया गया था। –

18

त्रुटि आपको बताता है कि वास्तव में समस्या क्या है (और डीबगर में चल रहे हैं या स्टैक ट्रेस पढ़ने आपको बता देंगे कहां समस्या है):

C# Collection was modified; enumeration operation may not execute.

आपकी समस्या पाश

foreach (KeyValuePair<int, int> kvp in rankings) { 
    // 
} 
है

जिसमें आप rankings संग्रह को संशोधित करते हैं।

var listOfRankingsToModify = new List<int>(); 

listOfRankingsToModify.Add(kvp.Key); 

साथ हमलावर लाइन बदलें और आप पाश से बाहर निकलने के बाद: विशेष रूप से, आक्रामक लाइन

rankings[kvp.Key] = rankings[kvp.Key] + 4; 

इससे पहले कि आप पाश में प्रवेश, निम्नलिखित पंक्ति जोड़ है

foreach(var key in listOfRankingsToModify) { 
    rankings[key] = rankings[key] + 4; 
} 

यह है कि, रिकॉर्ड करने के लिए आपको किन परिवर्तनों की आवश्यकता है, रिकॉर्ड करें और उन्हें उस संग्रह पर पुन: प्रयास किए बिना बनाएं जिसे आपको संशोधित करने की आवश्यकता है।

5

मुझे लगता है त्रुटि इस के कारण होता है:

foreach (KeyValuePair<int, int> kvp in rankings) 

रैंकिंग एक शब्दकोश है, जो IEnumerable है। इसे फ़ोरैच लूप में उपयोग करके, आप यह निर्दिष्ट कर रहे हैं कि आप प्रत्येक कुंजीवैलपेयर को डिक्शनरी से डिफर्ड तरीके से चाहते हैं। यही है, अगली KeyValuePair तब तक वापस नहीं आती है जब तक कि आपका लूप दोबारा शुरू न हो जाए।

लेकिन आप अपने पाश अंदर शब्दकोश संशोधित कर रहे हैं:

rankings[kvp.Key] = rankings[kvp.Key] + 4; 

जिसकी अनुमति नहीं है ... तो आप अपवाद मिलता है।

आप बस तुम कहाँ क्रियान्वित कर रहे हैं इस

foreach (KeyValuePair<int, int> kvp in rankings.ToArray()) 
2

समस्या कर सकता है:

rankings[kvp.Key] = rankings[kvp.Key] + 4; 

आप संग्रह आप एक foreach पाश में के माध्यम से पुनरावृत्ति कर रहे हैं संशोधित नहीं कर सकते। एक फोरच लूप को लूप को पुनरावृत्ति के दौरान अपरिवर्तनीय होने की आवश्यकता होती है।

इसके बजाय, एक मानक 'फॉर' लूप का उपयोग करें या एक नया लूप बनाएं जो आपकी मूल अपडेट करते समय एक प्रतिलिपि है और इसके माध्यम से पुनरावृत्ति करें।

13

जैसा कि अन्य ने बताया है, आप एक संग्रह को संशोधित कर रहे हैं जिस पर आप पुन: प्रयास कर रहे हैं और यही कारण है कि त्रुटि उत्पन्न हो रही है। अपमानजनक कोड के नीचे है:

foreach (KeyValuePair<int, int> kvp in rankings) 
{ 
    ..... 

    if((double)(similarModules/modules.Count)>0.6) 
    { 
     rankings[kvp.Key] = rankings[kvp.Key] + 4; // <--- This line is the problem 
    } 
    ..... 

क्या कोड से स्पष्ट नहीं हो सकता है ऊपर है जहां Enumerator से आता है। few years back about से ब्लॉग पोस्ट में एरिक लिपर्ट एक उदाहरण प्रदान करता है कि foreach लूप को कंपाइलर द्वारा विस्तारित किया जाता है। उत्पन्न कोड की तरह कुछ दिखेगा:

Enumerators can be used to read the data in the collection, but they cannot be used to modify the underlying collection.

हमें क्या त्रुटि को वापस लाता है कौन सा:

{ 
    IEnumerator<int> e = ((IEnumerable<int>)values).GetEnumerator(); // <-- This 
                 // is where the Enumerator 
                 // comes from. 
    try 
    { 
     int m; // OUTSIDE THE ACTUAL LOOP in C# 4 and before, inside the loop in 5 
     while(e.MoveNext()) 
     { 
      // loop code goes here 
     } 
    } 
    finally 
    { 
     if (e != null) ((IDisposable)e).Dispose(); 
    } 
} 

यदि आप IEnumerable के लिए MSDN प्रलेखीकरण (जो क्या GetEnumerator() रिटर्न) आप देखेंगे देखो संदेश राज्य और अन्य उत्तर पुनः राज्य, आप अंतर्निहित संग्रह को संशोधित कर रहे हैं।

+0

संभावित पाठक: कृपया डाउनवोट को अनदेखा करें, यह एनरडेज के फिट में किया गया था। ROMAN: यदि आप इस उत्तर को संपादित करते हैं तो मैं डाउनवोट को हटा दूंगा, इसकी पिछली सीमा सीमा और मुझे ऐसा करने नहीं देगा। – heisenberg

संबंधित मुद्दे

 संबंधित मुद्दे