在我的项目中,我尝试遍历值并调用它们上的函数。当调试时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次?
答案 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);
}
如果你这样做了,它会抛出一个异常,说集合在迭代时被修改了。这会立即提醒您注意这个问题。