public void OnNext(TableUpdate update) { _threadMarshaller.Dispatch( () => { if (update.Action == TableUpdateAction.Add) { var newRowIndex = _targetTable.AddRow(); Debug.Assert(update.RowIndex == newRowIndex); } else if (update.Action == TableUpdateAction.Delete) { _targetTable.DeleteRow(update.RowIndex); } else if (update.Action == TableUpdateAction.Update) { // BUG: When this line is called the original update.Column may not contain the same state as when the outside method is called. _targetTable.SetValue(update.Column.ColumnId, update.RowIndex, update.Column, update.RowIndex); } }); }
private void SynchroniseChanges(object state) { // Make copies to control exactly when we lock List <TableUpdate> updates; lock (_shared) { if (_updates.Count == 0) { return; } updates = _updates.DequeueAllToList(); } _threadMarshaller.Dispatch( () => { foreach (var update in updates.Where(TableUpdate.IsRowUpdate)) { if (update.Action == TableUpdateAction.Add) { _targetTable.AddRow(); } else if (update.Action == TableUpdateAction.Delete) { _targetTable.DeleteRow(update.RowIndex); } } // BUG: When this line is called the original update.Column may not contain the same state as when the outside method is called. foreach (var update in updates.Where(TableUpdate.IsColumnUpdate)) { _targetTable.SetValue(update.Column.ColumnId, update.RowIndex, update.Column, update.RowIndex); } }); }
/// <summary> /// Called when the timer ticks /// </summary> public void SynchroniseChanges() { // Make copies to control exactly when we lock List <TableUpdate> rowUpdatesAdd = null, rowUpdatesDelete = null; List <ITableColumnUpdater> colUpdaters; lock (_shared) { if (_rowUpdatesAdd.Count > 0) { rowUpdatesAdd = _rowUpdatesAdd.DequeueAllToList(); } if (_rowUpdatesDelete.Count > 0) { rowUpdatesDelete = _rowUpdatesDelete.DequeueAllToList(); } // Create a cloned list so we don't modify the main list from multiple threads colUpdaters = GetTableColumnUpdaters(); // Clear all the updates in the original version to indicate that there are no updates pending. foreach (var tableColumnUpdater in _columnUpdaters.Values) { tableColumnUpdater.Clear(); } } if (rowUpdatesAdd == null && rowUpdatesDelete == null && colUpdaters.Count == 0) { StartTimer(); return; } // Don't make dispatch granular so that we don't generate as many messages on the pump _marshaller.Dispatch(() => CopyChanges(rowUpdatesAdd, colUpdaters, rowUpdatesDelete)); }
public void SetValue <T>(string columnId, int rowIndex, T value) { _marshaller.Dispatch(() => _targetTargetTable.SetValue(columnId, rowIndex, value)); }