public static CancellableOperationStarter <V> StartablePut <U, V>(this IQueueSink <U> queue, U valueToPut, V successfulPut) { return(delegate(CancellationToken ctoken) { CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(ctoken); Func <Task <CancellableResult <V> > > taskSource = async delegate { AcquireWriteResult awr = await queue.AcquireWriteAsync(1, cts.Token); if (awr is AcquireWriteSucceeded) { AcquireWriteSucceeded aws = (AcquireWriteSucceeded)awr; System.Diagnostics.Debug.Assert(aws.ItemCount == 1); return new PutCancellableResult <U, V>(queue, valueToPut, successfulPut); } else if (awr is AcquireWriteFaulted) { AcquireWriteFaulted awf = (AcquireWriteFaulted)awr; throw awf.Exception; } else { // ReSharper disable once UnusedVariable AcquireWriteCancelled awc = (AcquireWriteCancelled)awr; throw new OperationCanceledException(); } }; Task <CancellableResult <V> > task; try { task = taskSource(); } catch (OperationCanceledException e) { #if NET451 var tcs = new TaskCompletionSource <CancellableResult <V> >(); tcs.SetException(e); tcs.SetCanceled(); task = tcs.Task; #else task = Task.FromCanceled <CancellableResult <V> >(e.CancellationToken); #endif } catch (Exception exc) { #if NET451 var tcs = new TaskCompletionSource <CancellableResult <V> >(); tcs.TrySetException(exc); task = tcs.Task; #else task = Task.FromException <CancellableResult <V> >(exc); #endif } return new CancellableOperation <V>(task, cts); }); }
public static async Task Enqueue <T>(this IQueueSink <T> queue, T item, CancellationToken ctoken) { AcquireWriteResult result = await queue.AcquireWriteAsync(1, ctoken); result.Visit <DBNull> ( new Func <AcquireWriteSucceeded, DBNull> ( succeeded => { System.Diagnostics.Debug.Assert(succeeded.ItemCount == 1); bool wasCancelled = false; if (ctoken.IsCancellationRequested) { wasCancelled = true; queue.ReleaseWrite(); } else { queue.ReleaseWrite(item); } if (wasCancelled) { throw new OperationCanceledException(ctoken); } return(DBNull.Value); } ), new Func <AcquireWriteCancelled, DBNull> ( cancelled => { throw new OperationCanceledException(ctoken); } ), new Func <AcquireWriteFaulted, DBNull> ( faulted => { throw faulted.Exception; } ) ); }