0

I call this below func with class list having 3 to 4 list items, in foreach loop i compare the system time with a set time and if the time of system exceeds them i remove that particular list from PIR_ConditionList by calling:

PIR_ConditionList.RemoveAll(element => element == Li);

but i get the error:

Collection was modified; enumeration operation may not execute. removing list item

I deduct it is an error in foreach as u cannot remove item when in loop. is there another way or a solution to this.

Task.Factory.StartNew(() =>
            {
                try
                {
                    while (PIR_ConditionList.Count>0)
                    {

                        foreach (var Li in PIR_ConditionList)
                        {
                            if (Li.dateimePresent < Li.datetimePlusFour)
                            {
                                var dimLevel = Li.dimLevel;
                                AcquisitionLoop.Luminaires.EnqueueCommand(new SetDimLVLNEW(new SetBrightnessNEW(Li.lumId, dimLevel, Li.lumNumId, Li.clusterId)));
                                Li.dateimePresent = DateTime.Now;
                                Thread.Sleep(10000);
                            }
                            else
                            {

                                PIR_ConditionList.RemoveAll(element => element == Li);

                            }
                        }

                    }
                }
                catch (Exception ee)
                {
                    fourMinTimer();
                }
            }); 
Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
Anil Gadiyar
  • 399
  • 1
  • 2
  • 16

2 Answers2

4

You can use a backwards for-loop instead + List.RemoveAt:

for(int i = PIR_ConditionList.Count -1 ; i >= 0; i--)
{
    var Li = PIR_ConditionList[i];
    if (Li.dateimePresent < Li.datetimePlusFour)
    {
        var dimLevel = Li.dimLevel;
        AcquisitionLoop.Luminaires.EnqueueCommand(new SetDimLVLNEW(new SetBrightnessNEW(Li.lumId, dimLevel, Li.lumNumId, Li.clusterId)));
        Li.dateimePresent = DateTime.Now;
        Thread.Sleep(10000);
    }
    else
        PIR_ConditionList.RemoveAt(i);
}

But since you are using multiple threads, note that List<T> is not thread safe.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
1

You must use for loop:

for (var i = 0; i< PIR_ConditionList.Count; i++)
{
    var Li = PIR_ConditionList[0];

    if (Li.dateimePresent < Li.datetimePlusFour)
    {
        var dimLevel = Li.dimLevel;
        AcquisitionLoop.Luminaires.EnqueueCommand(new SetDimLVLNEW(new SetBrightnessNEW(Li.lumId, dimLevel, Li.lumNumId, Li.clusterId)));
        Li.dateimePresent = DateTime.Now;
        Thread.Sleep(10000);
    }
    else
    {
        PIR_ConditionList.RemoveAt(i);

        i--;
    }
}

Try this code.

Alessandro D'Andria
  • 8,663
  • 2
  • 36
  • 32