/// <summary> /// StartableGet /// </summary> /// <param name="queue"></param> /// <param name="convertResult"></param> /// <param name="eofResult"></param> /// <typeparam name="U"></typeparam> /// <typeparam name="V"></typeparam> /// <returns></returns> /// <exception cref="Exception"></exception> /// <exception cref="OperationCanceledException"></exception> 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 { // ReSharper disable once UnusedVariable AcquireReadCancelled cancelledResult = (AcquireReadCancelled)arr; throw new OperationCanceledException(); } }; Task <CancellableResult <V> > task; try { task = Task.Run(taskSource); } catch (OperationCanceledException e) { task = Tasks.FromCanceled <CancellableResult <V> >(e); } catch (Exception exc) { task = Tasks.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 static async Task <Option <T> > Dequeue <T>(this IQueueSource <T> queue, CancellationToken ctoken) { AcquireReadResult result = await queue.AcquireReadAsync(1, ctoken); return(result.Visit <Option <T> > ( new Func <AcquireReadSucceeded, Option <T> > ( succeeded => { if (succeeded.ItemCount == 0) { return new None <T>(); } else { System.Diagnostics.Debug.Assert(succeeded.ItemCount == 1); bool wasCancelled = false; if (ctoken.IsCancellationRequested) { wasCancelled = true; queue.ReleaseRead(0); } else { queue.ReleaseRead(1); } if (wasCancelled) { throw new OperationCanceledException(ctoken); } return new Some <T>(((AcquireReadSucceeded <T>)succeeded).Items[0]); } } ), new Func <AcquireReadCancelled, Option <T> > ( cancelled => { throw new OperationCanceledException(ctoken); } ), new Func <AcquireReadFaulted, Option <T> > ( faulted => { throw faulted.Exception; } ) )); }
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); } }