Example #1
0
        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);
            });
        }
Example #2
0
        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; }
                       )
                   ));
        }
Example #3
0
            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);
                }
            }
Example #4
0
            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);
        }