Skip to content

Instantly share code, notes, and snippets.

@yuka1984
Created October 14, 2015 03:49
Show Gist options
  • Save yuka1984/991015eec48c4311d1e0 to your computer and use it in GitHub Desktop.
Save yuka1984/991015eec48c4311d1e0 to your computer and use it in GitHub Desktop.
マルチスレッドで複数のコレクション操作を排他制御して処理したかった ref: http://qiita.com/yu_ka1984/items/3090725fdc202657c90f
public class TransactionDispatchObservableCollection<T> : ObservableCollection<T>
{
/// <summary>
/// コレクションディスパッチャー
/// </summary>
public Dispatcher Dispatch { get; set; }
public DispatcherPriority Priority { get; set; } = DispatcherPriority.Background;
private object TransactLock = new object();
#region コンストラクタ
public TransactionDispatchObservableCollection(Dispatcher Dispatch)
{
this.Dispatch = Dispatch;
}
public TransactionDispatchObservableCollection(Dispatcher Dispatch, IEnumerable<T> collection) : base(collection)
{
this.Dispatch = Dispatch;
}
#endregion
/// <summary>
/// 関連処理を排他制御しながら実行します。
/// </summary>
/// <param name="action"></param>
public void TransactExcution(Action action)
{
lock (TransactLock)
{
action();
}
}
/// <summary>
/// 関連処理を排他制御しながら実行します。(非同期)
/// </summary>
public async Task TransactExcutionAsync(Action action)
{
await Task.Run(() => {
lock (TransactLock)
{
action();
}
});
}
protected override void ClearItems()
{
TransactExcution(() => base.ClearItems());
}
protected override void InsertItem(int index, T item)
{
TransactExcution(() => base.InsertItem(index, item));
}
protected override void MoveItem(int oldIndex, int newIndex)
{
TransactExcution(() => base.MoveItem(oldIndex, newIndex));
}
protected override void SetItem(int index, T item)
{
TransactExcution(() => base.SetItem(index, item));
}
protected override void RemoveItem(int index)
{
TransactExcution(() => base.RemoveItem(index));
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (this.Dispatch.Thread == Thread.CurrentThread)
{
base.OnCollectionChanged(e);
}
else
{
Action<NotifyCollectionChangedEventArgs> changed = OnCollectionChanged;
this.Dispatch.Invoke(changed, Priority, e);
}
}
}
await list.TransactExcutionAsync(() =>
{
if (!list.Any((x => x.Name == "Test")))
{
list.Add(model);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment