2011-08-27 7 views
0

У меня ошибка Коллекция была изменена; операция перечисления может не выполняться. на System.Collections.Queue.QueueEnumerator.MoveNext()Коллекция была изменена; операция перечисления не может быть выполнена

 Queue ReqQ = (Application["ReqQ"] != null) ? ((Queue)Application["ReqQ"]) : 
new Queue(50); 

      if (ReqQ != null) 
      { 
         foreach (object OReq in ReqQ) 
        { 
          string mId = (string)OReq; 
          if (mId.Split('~')[1].Equals(reqUid.Split('~')[1]) && (DateTime.Parse(mId.Split('~')[0]).AddMinutes(1 * int.Parse(string.IsNullOrEmpty(delay) ? "0" : delay)) > DateTime.Now)) 

          { 
             isSuccess = false; 
             break; 
          } 
        } 

       } 

       else 
       { 
          ReqQ = new Queue(10); 
          isSuccess = true; 
       } 

       if (isSuccess) 
       { 

         if (ReqQ.Count >= 10) //only keep last 10 messages in application cache 
           ReqQ.Dequeue(); 

            ReqQ.Enqueue(reqUid); 
            Application["ReqQ"] = ReqQ; 
       } 

ответ

2

Похоже, у вас есть одно семейство, которое вы сейчас читаете и модифицирующих из нескольких потоков (для различных запросов). Начнем с того, что это небезопасно, используя Queue - и это особенно Неверно, если вы повторяете сборку, пока вы изменяете ее в другой. (EDIT: Я только что заметил, что вы даже не используете коллекцию generic.Если вы используете .NET 4, нет причин использовать не общие коллекции ...)

Непонятно, вы пытаетесь достичь - вы можете отказаться от использования ConcurrentQueue<T>, но вам нужно знать, что к тому времени, когда вы выполнили итерацию над коллекцией, значения, которые вы прочитали, возможно, были опущены в другой поток.

+0

yes jon, есть несколько запросов, которые используют эту очередь во время. Это не всегда. 2-3 раза в день. Какой код я должен изменить для этого. –

+1

@cpsinghal: используйте блокировку или коллекцию, которая поддерживает одновременный доступ (например, ConcurrentQueue) –

Смежные вопросы