c#for循环退出1个循环后

时间:2016-01-04 21:14:46

标签: c#

在我的项目中,我尝试遍历值并调用它们上的函数。当调试时Count告诉我有2个值。我的函数在DispatcherTimer中运行

构造函数中的我的计时器:

DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(runSync);
dispatcherTimer.Interval = new TimeSpan(0, 0, syncTime);
dispatcherTimer.Start();

我的功能

private void runSync(object sender, EventArgs e)
{

    //I can see the value of count is 2 when using break points
    List<string> vals = repo.getRemovedAnswers();
    for (int i = 0; i < vals.Count(); i ++ )
    {
        //i do something with the element in my database

        // send back a confirmation that the delete is finished
        repo.setAnswerDeleted(vals.ElementAt(i));
        Console.WriteLine(i + " removed");
        //
    }              
    Console.WriteLine("syncing");

}

函数setAnswerDeleted在我的repo类中,它是一个void方法,所以不返回中断或任何东西。

 public List<String> getRemovedAnswers()
 {
    return _answersRemoved;
 }

public void setAnswerDeleted(string uniqueIdAnswer)
{
  _answersRemoved.RemoveAll( item => item == uniqueIdAnswer);

}

在日志中我可以看到循环运行每个调度器周期,onyl调用方法1次,为什么for循环在count == 2时没有运行2次?

2 个答案:

答案 0 :(得分:4)

尝试以这种方式更改代码:

private void runSync(object sender, EventArgs e)
{
    //I can see the value of count is 2 when using break points
    List<string> vals = repo.getRemovedAnswers();
    for (int i = vals.Count() - 1; i >= 0; i--)
    {
        repo.setAnswerDeleted(vals.ElementAt(i));
        Console.WriteLine(i + " removed");
    //
    }              
    Console.WriteLine("syncing");

}

你的迭代一次,因为你从列表中删除元素并将索引增加1但删除后的元素是previus长度 - 1,所以下一次检查vals.Count()返回1并且你的索引是1这样你的索引从1开始,第二步是0。

答案 1 :(得分:2)

问题是你正在迭代它时修改列表,所以它正在删除元素,并且Count()结果会在每个循环中向下移动。最佳做法是返回列表的副本,这样您就不会随意修改它。

List<string> getRemovedAnswers()
{
  .. logic
  List<string> previousReturn = ...
  return new List<string>(previousReturn);// Creates new list
}

另一个好的做法是使用foreach循环而不是索引。

foreach(var element in vals)
{
  repo.setAnswerDeleted(element);
}

如果你这样做了,它会抛出一个异常,说集合在迭代时被修改了。这会立即提醒您注意这个问题。