2017-11-14 8 views
0

レコードを送信しているBluetoothデバイスから通知を取得しようとしていて、UIを定期的に更新してレコードを表示しようとしています。以下のwhileループはUI更新を処理するために独自のスレッド内にあり、残りのモジュールは他のタスクを処理します。 gattCallbackは、BluetoothGattCallbackクラスのインスタンスで、受信したレコードのリストを追加し、getHistory()が呼び出されたときにそのリストを返します。foreachループでコレクションが変更されました

私の問題は、私はforeachラインをヒットしたときに、非常に多くの反復の後、私はエラーが出るということです。

System.InvalidOperationException: Collection was modified; enumeration operation may not execute. 
私の知る限り

historyはここかどこか他で更新されていないが、私の私はエラーで混乱しています。私は具体的にはforeachの間に修正を避けるために、記録履歴のコピーをgetHistory()で検索します。誰かがそれを引き起こしているかもしれないと示唆するためのヒントを提案することはできますか?

これはAndroid 6.1.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); 
     } 

答えて

2

I specifically retrieve a copy of the record history through getHistory() to avoid modifying it during the foreach.

あなたはコピーを取得していることは確かか?この実装を想像:

public List<Record> getHistory() { 
    return history; 
} 

これはhistoryのコピーを返しますが、history自体への直接参照しません。 2つの異なる場所でこのメソッドを呼び出すと、返された値のいずれかが変更された場合、その戻り値に影響します。

あなたがコピーをしたい場合、あなたはこのような何かをする必要があります:

public List<Record> getHistory() { 
    return new ArrayList<>(history); 
} 
+0

えーえは、総理にかなっているあなたに感謝します。それが私の埋め込まれた終わりだったら、それは私が考えた最初のことです!それは今治療を働く:) – Hester

関連する問題