非同期処理でリストを更新するとExceptionが発生します。
そこで、EnableCollectionSynchronizationを使用して、lock処理を行います。
// Lock用のobjectを作成
private object lockObject = new object();
public ObservableCollection<Myitem> Result { get; set; }
public コンストラクタ()
{
// 非同期での変更を可能にする
Result = new ObservableCollection<Myitem>();
BindingOperations.EnableCollectionSynchronization(this.Result, lockObject);
}
// これは非同期処理
private void Test()
{
Result.Clear();
for (int i = 0; i < 100; i++)
{
var item = new MyItem();
Result.Add(item);
}
}
なんとなく、これで良いと思っていたんだけど、これだと稀にExceptionが出るみたい。
非同期で処理すると、
System.ArgumentOutOfRangeException
インデックスは一覧の 範囲内になければなりません
(Index must be within the bounds of the List)
LockはEnableCollectionSynchronizationメソッドを使うだけじゃなくて、
更新される箇所にも使う必要があるみたい。
// Lock用のobjectを作成
private object lockObject = new object();
public ObservableCollection<Myitem> Result { get; set; }
public コンストラクタ()
{
// 非同期での変更を可能にする
Result = new ObservableCollection<Myitem>();
BindingOperations.EnableCollectionSynchronization(this.Result, lockObject);
}
// これは非同期処理
private void Test()
{
// Lockを取得
lock(lockObject)
{
Result.Clear();
for (int i = 0; i < 100; i++)
{
var item = new MyItem();
Result.Add(item);
}
}
}
例ではメソッドを全て囲っていますが、ClearやAddのみを対象としたほうがレスポンス良いかなと思います。