Created
November 24, 2014 19:25
-
-
Save dealproc/e01e8aac2c2e447f651a to your computer and use it in GitHub Desktop.
ThreadSafeObservableCollection.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.ObjectModel; | |
using System.Threading; | |
using System.Windows.Threading; | |
using Kiosk.Error; | |
using Kiosk.Globals; | |
namespace Kiosk.Gui.Types | |
{ | |
[Serializable] | |
public class ThreadSafeObservableCollection<T> : ObservableCollection<T> | |
{ | |
[NonSerialized] private ReaderWriterLock _lock; | |
protected override void ClearItems() | |
{ | |
try | |
{ | |
if (Constants.MainDispatcher.CheckAccess()) | |
{ | |
if (null == _lock) | |
{ | |
_lock = new ReaderWriterLock(); | |
} | |
var c = _lock.UpgradeToWriterLock(-1); | |
base.ClearItems(); | |
_lock.DowngradeFromWriterLock(ref c); | |
} | |
else | |
{ | |
Constants.MainDispatcher.Invoke(DispatcherPriority.DataBind, | |
(SendOrPostCallback) delegate { Clear(); }); | |
} | |
} | |
catch (Exception ex) | |
{ | |
Logging.LogException(ex); | |
} | |
} | |
protected override void InsertItem(int index, T item) | |
{ | |
try | |
{ | |
if (Constants.MainDispatcher.CheckAccess()) | |
{ | |
if (index > Count) | |
return; | |
if (null == _lock) | |
{ | |
_lock = new ReaderWriterLock(); | |
} | |
var c = _lock.UpgradeToWriterLock(-1); | |
base.InsertItem(index, item); | |
_lock.DowngradeFromWriterLock(ref c); | |
} | |
else | |
{ | |
var e = new object[] {index, item}; | |
Constants.MainDispatcher.Invoke(DispatcherPriority.DataBind, | |
(SendOrPostCallback) delegate { InsertItemImpl(e); }, e); | |
} | |
} | |
catch (Exception ex) | |
{ | |
Logging.LogException(ex); | |
} | |
} | |
private void InsertItemImpl(object[] e) | |
{ | |
try | |
{ | |
if (Constants.MainDispatcher.CheckAccess()) | |
{ | |
InsertItem((int) e[0], (T) e[1]); | |
} | |
else | |
{ | |
Constants.MainDispatcher.Invoke(DispatcherPriority.DataBind, | |
(SendOrPostCallback) delegate { InsertItemImpl(e); }); | |
} | |
} | |
catch (Exception ex) | |
{ | |
Logging.LogException(ex); | |
} | |
} | |
protected override void MoveItem(int oldIndex, int newIndex) | |
{ | |
try | |
{ | |
if (Constants.MainDispatcher.CheckAccess()) | |
{ | |
if (oldIndex >= Count | newIndex >= Count | oldIndex == newIndex) | |
return; | |
if (null == _lock) | |
{ | |
_lock = new ReaderWriterLock(); | |
} | |
var c = _lock.UpgradeToWriterLock(-1); | |
base.MoveItem(oldIndex, newIndex); | |
_lock.DowngradeFromWriterLock(ref c); | |
} | |
else | |
{ | |
var e = new object[] {oldIndex, newIndex}; | |
Constants.MainDispatcher.Invoke(DispatcherPriority.DataBind, | |
(SendOrPostCallback) delegate { MoveItemImpl(e); }, e); | |
} | |
} | |
catch (Exception ex) | |
{ | |
Logging.LogException(ex); | |
} | |
} | |
private void MoveItemImpl(object[] e) | |
{ | |
try | |
{ | |
if (Constants.MainDispatcher.CheckAccess()) | |
{ | |
MoveItem((int) e[0], (int) e[1]); | |
} | |
else | |
{ | |
Constants.MainDispatcher.Invoke(DispatcherPriority.DataBind, | |
(SendOrPostCallback) delegate { MoveItemImpl(e); }); | |
} | |
} | |
catch (Exception ex) | |
{ | |
Logging.LogException(ex); | |
} | |
} | |
protected override void RemoveItem(int index) | |
{ | |
try | |
{ | |
if (Constants.MainDispatcher.CheckAccess()) | |
{ | |
if (index >= Count) | |
return; | |
if (null == _lock) | |
{ | |
_lock = new ReaderWriterLock(); | |
} | |
var c = _lock.UpgradeToWriterLock(-1); | |
base.RemoveItem(index); | |
_lock.DowngradeFromWriterLock(ref c); | |
} | |
else | |
{ | |
Constants.MainDispatcher.Invoke(DispatcherPriority.DataBind, | |
(SendOrPostCallback) delegate { RemoveItem(index); }, index); | |
} | |
} | |
catch (Exception ex) | |
{ | |
Logging.LogException(ex); | |
} | |
} | |
protected override void SetItem(int index, T item) | |
{ | |
try | |
{ | |
if (Constants.MainDispatcher.CheckAccess()) | |
{ | |
if (null == _lock) | |
{ | |
_lock = new ReaderWriterLock(); | |
} | |
var c = _lock.UpgradeToWriterLock(-1); | |
base.SetItem(index, item); | |
_lock.DowngradeFromWriterLock(ref c); | |
} | |
else | |
{ | |
var e = new object[] {index, item}; | |
Constants.MainDispatcher.Invoke(DispatcherPriority.DataBind, | |
(SendOrPostCallback) delegate { SetItemImpl(e); }, e); | |
} | |
} | |
catch (Exception ex) | |
{ | |
Logging.LogException(ex); | |
} | |
} | |
private void SetItemImpl(object[] e) | |
{ | |
try | |
{ | |
if (Constants.MainDispatcher.CheckAccess()) | |
{ | |
SetItem((int) e[0], (T) e[1]); | |
} | |
else | |
{ | |
Constants.MainDispatcher.Invoke(DispatcherPriority.DataBind, | |
(SendOrPostCallback) delegate { SetItemImpl(e); }); | |
} | |
} | |
catch (Exception ex) | |
{ | |
Logging.LogException(ex); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment