我试图从蓝牙设备发送记录的通知,并定期更新UI以显示记录。下面的while循环位于自己的线程中以处理UI更新,而模块的其余部分负责其他任务。 gattCallback
是BluetoothGattCallback
类的一个实例,它添加到已接收记录的列表中,并在调用getHistory()
时返回该列表。
我的问题是当我点击foreach
行时,经过这么多次迭代后我得到一个错误:
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
据我所知,history
未在此处或我的代码中的任何其他地方进行更新,因此我对此错误感到困惑。我专门通过getHistory()
检索记录历史记录的副本,以避免在foreach
期间对其进行修改。任何人都可以建议可能导致它的原因或任何提示吗?
自从从Android 6.0.1上的Moto G Play切换到Android 7.1.1上的Moto E4后,这可能会引起问题。
// Periodically check to see what needs updating
while (!finishedDisplayThread)
{
// See if there are any new records to display
int count;
List<Record> history = gattCallback.getHistory();
if (history == null)
{
count = 0;
}
else
{
count = history.Count;
}
// Only update the display if it has changed
if(count != prevCount)
{
prevCount = count;
List<string> recordList = new List<string>();
if (history == null)
{
recordList = new List<string>();
recordList.Add("No history.");
}
else
{
foreach (Record record in history)
{
recordList.Add(record.ToRow());
}
}
//Update the display
RunOnUiThread(() =>
{
ListAdapter = new ArrayAdapter<string>(this,
Resource.Layout.ListItemLayout,
recordList);
recordCountText.Text = "" + count;
});
}
Thread.Sleep(100);
}
答案 0 :(得分:2)
我通过
getHistory()
专门检索记录历史记录的副本,以避免在foreach期间对其进行修改。
您确定要获得副本吗?想象一下这个实现:
public List<Record> getHistory() {
return history;
}
这将不返回history
的副本,但直接引用history
本身。如果两个不同的位置调用此方法,则对其中一个返回值的任何更改都将影响另一个返回值。
如果你想要一份副本,你必须做这样的事情:
public List<Record> getHistory() {
return new ArrayList<>(history);
}