public static CancellableOperationStarter <V> StartableGet <U, V>(this IQueueSource <U> queue, Func <U, V> convertResult, V eofResult) { return(delegate(CancellationToken ctoken) { CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(ctoken); Func <Task <CancellableResult <V> > > taskSource = async delegate() { AcquireReadResult arr = await queue.AcquireReadAsync(1, cts.Token); if (arr is AcquireReadSucceeded <U> ) { AcquireReadSucceeded <U> succeededResult = (AcquireReadSucceeded <U>)arr; if (succeededResult.ItemCount == 1) { return new GetCancellableResult <U, V>(queue, succeededResult.Items[0], convertResult); } else { System.Diagnostics.Debug.Assert(succeededResult.ItemCount == 0); return new GetEofCancellableResult <U, V>(queue, eofResult); } } else if (arr is AcquireReadFaulted) { AcquireReadFaulted faultedResult = (AcquireReadFaulted)arr; throw faultedResult.Exception; } else { AcquireReadCancelled cancelledResult = (AcquireReadCancelled)arr; throw new OperationCanceledException(); } }; Task <CancellableResult <V> > task = null; try { task = Task.Run(taskSource); } catch (OperationCanceledException e) { task = Task.FromCanceled <CancellableResult <V> >(e.CancellationToken); } catch (Exception exc) { task = Task.FromException <CancellableResult <V> >(exc); } return new CancellableOperation <V>(task, cts); }); }
public async Task <AcquireReadResult> AcquireReadAsync(int desiredItems, CancellationToken ctoken) { AcquireReadResult parentResult = await parent.AcquireReadAsync(desiredItems, ctoken); if (parentResult is AcquireReadSucceeded <T> ) { AcquireReadSucceeded <T> parentSuccess = (AcquireReadSucceeded <T>)parentResult; ImmutableList <U> sequence = ImmutableList <U> .Empty.AddRange(parentSuccess.Items.Select(func)); return(new AcquireReadSucceeded <U>(parentSuccess.Offset, sequence)); } else { return(parentResult); } }
public async Task <AcquireReadResult> AcquireReadAsync(int desiredItems, CancellationToken ctoken) { AcquireReadResult parentResult = await parent.AcquireReadAsync(desiredItems, ctoken); if (parentResult is AcquireReadSucceeded <T> ) { AcquireReadSucceeded <T> parentSuccess = (AcquireReadSucceeded <T>)parentResult; ImmutableList <Tuple <int, T> > sequence = ImmutableList <Tuple <int, T> > .Empty; foreach (var x in Enumerable.Range(0, parentSuccess.ItemCount)) { sequence = sequence.Add(new Tuple <int, T>(index + x, parentSuccess.Items[x])); } return(new AcquireReadSucceeded <Tuple <int, T> >(parentSuccess.Offset, sequence)); } else { return(parentResult); } }
private async Task SimpleQueueTestAsync() { AsyncQueue <int> queue = new AsyncQueue <int>(11); Func <Task> producer = async delegate() { #region for (int i = 0; i < 20; ++i) { System.Diagnostics.Debug.WriteLine("Acquiring write..."); AcquireWriteResult result = await queue.AcquireWriteAsync(1, CancellationToken.None); result.Visit <DBNull> ( new Func <AcquireWriteSucceeded, DBNull> ( succeeded => { System.Diagnostics.Debug.WriteLine("Write-acquire succeeded, offset " + succeeded.Offset + ", acquired " + succeeded.ItemCount + " spaces"); Assert.AreEqual(1, succeeded.ItemCount); if (succeeded.ItemCount >= 1) { System.Diagnostics.Debug.WriteLine("Releasing write (1)..."); queue.ReleaseWrite(i); } else { System.Diagnostics.Debug.WriteLine("Releasing write (0)..."); queue.ReleaseWrite(); } return(DBNull.Value); } ), new Func <AcquireWriteCancelled, DBNull> ( cancelled => { throw new OperationCanceledException(); } ), new Func <AcquireWriteFaulted, DBNull> ( faulted => { throw faulted.Exception; } ) ); } System.Diagnostics.Debug.WriteLine("Writing EOF..."); queue.WriteEof(); #endregion }; Func <Task> consumer = async delegate() { #region bool more = true; while (more) { System.Diagnostics.Debug.WriteLine("Acquiring read..."); const int ACQUIRE_COUNT = 3; AcquireReadResult result = await queue.AcquireReadAsync(ACQUIRE_COUNT, CancellationToken.None); result.Visit <DBNull> ( new Func <AcquireReadSucceeded, DBNull> ( succeeded => { System.Diagnostics.Debug.WriteLine("Read-acquire succeeded, offset " + succeeded.Offset + ", acquired " + succeeded.ItemCount + " items"); Assert.IsInstanceOfType(succeeded, typeof(AcquireReadSucceeded <int>)); if (succeeded is AcquireReadSucceeded <int> ) { AcquireReadSucceeded <int> succeeded2 = (AcquireReadSucceeded <int>)succeeded; System.Diagnostics.Debug.WriteLine("{ " + string.Join(", ", succeeded2.Items) + " }"); } if (succeeded.ItemCount < ACQUIRE_COUNT) { System.Diagnostics.Debug.WriteLine("Setting \"more\" flag to false..."); more = false; } System.Diagnostics.Debug.WriteLine("Releasing read (" + succeeded.ItemCount + ")..."); queue.ReleaseRead(succeeded.ItemCount); return(DBNull.Value); } ), new Func <AcquireReadCancelled, DBNull> ( cancelled => { throw new OperationCanceledException(); } ), new Func <AcquireReadFaulted, DBNull> ( faulted => { throw faulted.Exception; } ) ); } #endregion }; Task tProducer = Task.Run(producer); Task tConsumer = Task.Run(consumer); await Task.WhenAll(tProducer, tConsumer); }