public WorkItem(WorkQueueOperation operation, TKey key, TValue value) { this.operation = operation; this.key = key; this.value = value; this.consumed = false; }
public bool TryChange(WorkQueueOperation newOperation, TValue newValue) { lock (lockObject) { if (consumed) { return(false); } // can't change existing add to add or existing delete to delete if (newOperation == operation && operation != WorkQueueOperation.Update) { throw new InvalidOperationException(); } // change existing update or add to use new value on update else if (newOperation == WorkQueueOperation.Update && (operation == WorkQueueOperation.Add || operation == WorkQueueOperation.Update)) { value = newValue; } // change an existing delete to an update on add else if (newOperation == WorkQueueOperation.Add && operation == WorkQueueOperation.Remove) { operation = WorkQueueOperation.Update; value = newValue; } // remove an existing add on delete else if (newOperation == WorkQueueOperation.Remove && operation == WorkQueueOperation.Add) { operation = WorkQueueOperation.Nothing; value = default(TValue); } // remove an existing update on delete else if (newOperation == WorkQueueOperation.Remove && operation == WorkQueueOperation.Update) { operation = WorkQueueOperation.Remove; value = default(TValue); } // the remaining conditions are all invalid: // - change an existing add to an update // - change an existing delete to an update else { throw new InvalidOperationException(); } return(true); } }
private void QueueWork(WorkQueueOperation operation, TKey key, TValue value) { bool alreadyExists; WorkItem workItem; if (!(alreadyExists = workByKey.TryGetValue(key, out workItem)) || !workItem.TryChange(operation, value)) { workItem = new WorkItem(operation, key, value); workByKey[key] = workItem; if (!workQueue.Post(workItem)) { throw new InvalidOperationException(); } } else if (alreadyExists) { WorkChangeCount++; } }