アイテムにバインドされた Grid がList<T>
あります。ユーザーが「更新」を押すたびに、データベースから変更が取得され、バインドされたリストが更新されます。グリッドにアイテムが重複して追加されるという問題が発生しましたが、その理由がわかりません。
List<int>
データベース呼び出しは、変更されたレコード ID と、変更さList<MyClass>
れたレコードの更新されたデータの2 つの値を返します。更新する必要があるものを見つけるためにデバッグしている既存のコード コードは、次のようになります。
public void FindUpdates(IList<MyClass> existingRecords,
IList<MyClass> updatedRecords,
List<int> updatedIds,
out IDictionary<int, int> existing,
out IDictionary<int, int> updated,
out List<int> updates,
out List<int> removes,
out List<int> adds)
{
updates = new List<int>();
removes = new List<int>();
adds = new List<int>();
existing = FindUpdated(existingRecords, updatedIds);
updated = FindUpdated(updatedRecords, updatedIds);
if (updatedIds != null)
{
// split add/update and remove
foreach (int id in updatedIds)
{
if (!existing.ContainsKey(id))
adds.Add(id);
else if (updated.ContainsKey(id))
updates.Add(id);
else
removes.Add(id);
}
WriteToLog(updatedIds, adds, updates, removes);
}
}
private IDictionary<int, int> FindUpdated(IList<MyClass> records, List<int> updatedIds)
{
IDictionary<int, int> foundItems = new Dictionary<int, int>();
if (records != null && updatedIds != null)
{
for (int i = 0; i < records.Count; i++)
{
IMyClass r = records[i] as IMyClass ;
if (r != null && !r.IsDisposed)
{
if (updatedIds.Contains(r.Id))
{
foundItems.Add(r.Id, i);
}
}
}
}
return foundItems;
}
呼び出しの結果、FindUpdates()
既存Dictionary<Id, Data>
のレコードの 、Dictionary<Id, Data>
それらを置き換える更新されたレコードの 、およびList<int>
データ ソースからアイテムを追加、削除、または更新する必要がある ID の を取得します。
場合によっては、レコードがグリッドに 2 回追加されることがありますが、このコードのどこが間違っているのか、一生わからないことがあります。
これらのインスタンスの 1 つからログ ファイルを取得したところ、次の一連のイベントを明確に確認できます。
- データリストにアイテム#2を追加
- 20分後、アイテム#2が再びデータリストに追加されます
WriteToLog()
2番目の追加から、
updatedIds
値 1、2、および 3 を含むadds
1 と 2 を含むupdates
3個入り
他のログ エントリに基づいて、アイテム #2 が以前に追加され、削除されていないことを明確に確認できexistingRecords
ます。さらに、アイテム #2 は最初の追加と 2 番目の追加の間に数回正常に更新されたため、理論上のコードは機能するはずです。UI のスクリーンショットもあり、データのグリッドにアイテム #2 の両方のコピーが表示されています。updates
adds
ノート...
IsDisposed
アイテムのオーバーライドさ.Dispose()
れたメソッドでのみ true に設定されます。こんなことにはならなかったと思います。編集:それ以来、ログステートメントを追加しましたが、これが発生したときに
IsDisposed
設定されていないことを確認できtrue
ます。これは数人の異なるユーザーに数回発生しているため、一度だけではありません。ただし、オンデマンドで問題を再現することはできません。
レコードのグリッドはかなり大きくなり、平均して数千項目になります。
DB呼び出しが無効な値を返す、または同じアイテムを持たないリストを返すという考えを排除していませんが、それが結果にどのように影響するかはわかりません
このバグの動作を確認できたのは、いくつかのテストを実行していて、他のユーザーがレコード #2 をかなり頻繁に変更していたときです。
これはすべてバックグラウンド スレッドで実行されます
ログに基づくと、これは一度だけ実行されていました。前は 1 分前に実行され、次は 2 分後に実行されました。
ログ ファイルから、項目 2 が正しく更新された後、2 回目の追加が誤って行われたことがわかります。したがって、このコードは数回前に既存のデータ セットで機能していました。
上記のコードに、これを引き起こす可能性のあるものはありますか? それとも、私が気付いていない C# のまれな既知の問題で、これが発生する可能性がありますか?