Ejemplo n.º 1
0
        /// <summary>
        /// Get all pages in a paginated collection.
        /// </summary>
        /// <remarks>
        /// If <paramref name="progress"/> is non-<see langword="null"/>, the first call to
        /// <see cref="IProgress{T}.Report"/> will specify the <paramref name="page"/>
        /// argument. After each task to obtain to the next page of results completes,
        /// the <see cref="IProgress{T}.Report"/> method will be called again with the
        /// new page of results.
        /// <para>
        /// This method determines that the end of the collection is reached when either of
        /// the following conditions is true.
        /// </para>
        /// <list type="bullet">
        /// <item>The <see cref="ReadOnlyCollectionPage{T}.CanHaveNextPage"/> property returns <see langword="false"/>.</item>
        /// <item>An empty page is reached.</item>
        /// </list>
        /// </remarks>
        /// <typeparam name="T">The type of elements in the collection.</typeparam>
        /// <param name="page">The first page in the collection.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
        /// <param name="progress">An optional callback object to receive progress notifications. If this is <see langword="null"/>, no progress notifications are sent.</param>
        /// <returns>
        /// A <see cref="Task"/> object representing the asynchronous operation. When the operation
        /// completes successfully, the <see cref="Task{TResult}.Result"/> property will contain a
        /// read-only collection containing the complete set of results from the paginated collection.
        /// </returns>
        /// <exception cref="ArgumentNullException">If <paramref name="page"/> is <see langword="null"/>.</exception>
        public static Task <ReadOnlyCollection <T> > GetAllPagesAsync <T>(this ReadOnlyCollectionPage <T> page, CancellationToken cancellationToken, IProgress <ReadOnlyCollectionPage <T> > progress)
        {
            if (page == null)
            {
                throw new ArgumentNullException("page");
            }

            List <T> result = new List <T>();
            ReadOnlyCollectionPage <T> currentPage = page;
            Func <bool> condition = () => currentPage != null;
            Func <Task> body      =
                () =>
            {
                if (progress != null)
                {
                    progress.Report(currentPage);
                }

                result.AddRange(currentPage);
                if (currentPage.CanHaveNextPage && currentPage.Count > 0)
                {
                    return(currentPage.GetNextPageAsync(cancellationToken)
                           .Select(task => currentPage = task.Result));
                }
                else
                {
                    currentPage = null;
                    return(CompletedTask.Default);
                }
            };

            return(TaskBlocks.While(condition, body)
                   .Select(_ => result.AsReadOnly()));
        }
Ejemplo n.º 2
0
        public void TestWhile2_Loop3_NullTaskBody()
        {
            AsyncWhileCondition whileCondition = AsyncWhileCondition.True();
            WhileBody           whileBody      = new WhileBody(3, DelegateBehavior.NullTask);

            // declaring these makes it clear we are testing the correct overload
            Func <Task <bool> > condition = whileCondition.EvaluateAsync;
            Func <Task>         body      = whileBody.ExecuteAsync;

            Task whileTask = null;

            try
            {
                whileTask = TaskBlocks.While(condition, body);
                whileTask.Wait();
                Assert.Fail("Expected an exception");
            }
            catch (AggregateException ex)
            {
                Assert.IsNotNull(whileTask);
                Assert.AreEqual(TaskStatus.Faulted, whileTask.Status);
                Assert.AreEqual(1, ex.InnerExceptions.Count);
                Assert.IsInstanceOfType(ex.InnerExceptions[0], typeof(InvalidOperationException));

                Assert.AreEqual(whileBody.MaxExecutions, whileCondition.EvaluateAsyncCount);
                Assert.AreEqual(whileBody.MaxExecutions, whileCondition.SyncPartEvaluateAsyncCount);
                Assert.AreEqual(whileBody.MaxExecutions, whileBody.SyncPartExecutionCount);
                Assert.AreEqual(whileBody.MaxExecutions - 1, whileBody.ExecutionCount);
            }
        }
Ejemplo n.º 3
0
        public void TestWhile2_Loop3_SyncFaultedCondition()
        {
            AsyncWhileCondition whileCondition = new AsyncWhileCondition(3, DelegateBehavior.SyncFaulted);
            WhileBody           whileBody      = new WhileBody();

            // declaring these makes it clear we are testing the correct overload
            Func <Task <bool> > condition = whileCondition.EvaluateAsync;
            Func <Task>         body      = whileBody.ExecuteAsync;

            Task whileTask = null;

            try
            {
                whileTask = TaskBlocks.While(condition, body);
                whileTask.Wait();
                Assert.Fail("Expected an exception");
            }
            catch (AggregateException ex)
            {
                Assert.IsNotNull(whileTask);
                Assert.AreEqual(TaskStatus.Faulted, whileTask.Status);
                Assert.AreEqual(1, ex.InnerExceptions.Count);
                Assert.AreSame(whileCondition.ExpectedException, ex.InnerExceptions[0]);

                Assert.AreEqual(whileCondition.TotalIterations + 1, whileCondition.SyncPartEvaluateAsyncCount);
                Assert.AreEqual(whileCondition.TotalIterations, whileCondition.EvaluateAsyncCount);
                Assert.AreEqual(whileCondition.TotalIterations, whileBody.SyncPartExecutionCount);
                Assert.AreEqual(whileCondition.TotalIterations, whileBody.ExecutionCount);
            }
        }
Ejemplo n.º 4
0
#pragma warning restore 1998

        #region WhileAsyncBuildingBlock
        public Task While()
        {
            Stack <int> workList = new Stack <int>(new[] { 3, 5, 7 });

            return(TaskBlocks.While(
                       () => HasItemsAsync(workList),
                       () => ProcessWorkItemAsync(workList.Pop())));
        }
Ejemplo n.º 5
0
        public void TestWhile2_NullConditionFunction()
        {
            // declaring these makes it clear we are testing the correct overload
            Func <Task <bool> > condition = null;
            Func <Task>         body      = new WhileBody().ExecuteAsync;

            TaskBlocks.While(condition, body);
        }
Ejemplo n.º 6
0
        public void TestWhile1_Loop3_Success()
        {
            WhileCondition whileCondition = new WhileCondition(3);
            WhileBody      whileBody      = new WhileBody();

            // declaring these makes it clear we are testing the correct overload
            Func <bool> condition = whileCondition.Evaluate;
            Func <Task> body      = whileBody.ExecuteAsync;

            Task whileTask = TaskBlocks.While(condition, body);

            whileTask.Wait();

            Assert.AreEqual(whileCondition.TotalIterations + 1, whileCondition.EvaluateCount);
            Assert.AreEqual(whileCondition.TotalIterations, whileBody.SyncPartExecutionCount);
            Assert.AreEqual(whileCondition.TotalIterations, whileBody.ExecutionCount);
        }
Ejemplo n.º 7
0
        public void TestWhile1_NullBodyFunction()
        {
            WhileCondition whileCondition = new WhileCondition(0);

            // declaring these makes it clear we are testing the correct overload
            Func <bool> condition = whileCondition.Evaluate;
            Func <Task> body      = null;

            try
            {
                TaskBlocks.While(condition, body);
            }
            catch
            {
                Assert.AreEqual(0, whileCondition.EvaluateCount);
                throw;
            }
        }
Ejemplo n.º 8
0
        protected internal override Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            // RFC 2046
            //
            // The Content-Type field for multipart entities requires one parameter,
            // "boundary". The boundary delimiter line is then defined as a line
            // consisting entirely of two hyphen characters ("-", decimal value 45)
            // followed by the boundary parameter value from the Content-Type header
            // field, optional linear whitespace, and a terminating CRLF.
            //

            byte[] buffer;
            var    sb = new StringBuilder();

            sb.Append('-').Append('-');
            sb.Append(boundary);
            sb.Append('\r').Append('\n');

            int         i         = 0;
            Func <bool> condition = () => i < nested_content.Count;
            Func <Task> body      =
                () =>
            {
                var c = nested_content[i];

                foreach (var h in c.Headers)
                {
                    sb.Append(h.Key);
                    sb.Append(':').Append(' ');
                    foreach (var v in h.Value)
                    {
                        sb.Append(v);
                    }
                    sb.Append('\r').Append('\n');
                }
                sb.Append('\r').Append('\n');

                buffer    = Encoding.ASCII.GetBytes(sb.ToString());
                sb.Length = 0;

                return(stream.WriteAsync(buffer, 0, buffer.Length)
                       .Then(_ => c.SerializeToStreamAsync(stream, context))
                       .Select(
                           _ =>
                {
                    if (i != nested_content.Count - 1)
                    {
                        sb.Append('\r').Append('\n');
                        sb.Append('-').Append('-');
                        sb.Append(boundary);
                        sb.Append('\r').Append('\n');
                    }

                    i++;
                }));
            };

            Func <Task, Task> continuationFunction =
                task =>
            {
                sb.Append('\r').Append('\n');
                sb.Append('-').Append('-');
                sb.Append(boundary);
                sb.Append('-').Append('-');
                sb.Append('\r').Append('\n');

                buffer = Encoding.ASCII.GetBytes(sb.ToString());
                return(stream.WriteAsync(buffer, 0, buffer.Length));
            };

            return(TaskBlocks.While(condition, body)
                   .Then(continuationFunction));
        }