コード例 #1
0
ファイル: TaskUtilities.cs プロジェクト: edgarrs/BuildXL
        /// <summary>
        /// Awaits for a given task while periodically calling <paramref name="action"/>.
        /// </summary>
        /// <typeparam name="TResult">Return type of the task</typeparam>
        /// <param name="task">The task to await</param>
        /// <param name="period">Period at which to call <paramref name="action"/></param>
        /// <param name="action">Action to periodically call.  The action receives elapsed time since this method was called.</param>
        /// <param name="reportImmediately">Whether <paramref name="action"/> should be called immediately.</param>
        /// <param name="reportAtEnd">Whether <paramref name="action"/> should be called at when </param>
        /// <returns>The result of the task.</returns>
        public static async Task <TResult> AwaitWithProgressReporting <TResult>(
            Task <TResult> task,
            TimeSpan period,
            Action <TimeSpan> action,
            bool reportImmediately = true,
            bool reportAtEnd       = true)
        {
            var startTime = DateTime.UtcNow;
            var timer     = new StoppableTimer(
                () =>
            {
                action(DateTime.UtcNow.Subtract(startTime));
            },
                dueTime: reportImmediately ? 0 : (int)period.TotalMilliseconds,
                period: (int)period.TotalMilliseconds);

            using (timer)
            {
                await task.ContinueWith(t =>
                {
                    return(timer.StopAsync());
                }).Unwrap();

                // report once at the end
                if (reportAtEnd)
                {
                    action(DateTime.UtcNow.Subtract(startTime));
                }

                return(await task);
            }
        }
コード例 #2
0
ファイル: TaskUtilities.cs プロジェクト: edgarrs/BuildXL
        /// <summary>
        /// Awaits given tasks, periodically calling <paramref name="action"/>.
        /// </summary>
        /// <typeparam name="TItem">Type of the collection to iterate over.</typeparam>
        /// <typeparam name="TResult">Type of the tasks' result.</typeparam>
        /// <param name="collection">Collection to iterate over.</param>
        /// <param name="taskSelector">Function to use to select a task for a given item from the given collection.</param>
        /// <param name="action">
        /// Action to call periodically (as specified by <paramref name="period"/>).
        /// The action receives
        ///   (1) total elapsed time,
        ///   (2) all original items, and
        ///   (3) a collection of non-finished items
        /// </param>
        /// <param name="period">Period at which to call <paramref name="action"/>.</param>
        /// <returns>The results of inidvidual tasks.</returns>
        public static async Task <TResult[]> AwaitWithProgressReporting <TItem, TResult>(
            IReadOnlyCollection <TItem> collection,
            Func <TItem, Task <TResult> > taskSelector,
            Action <TimeSpan, IReadOnlyCollection <TItem>, IReadOnlyCollection <TItem> > action,
            TimeSpan period)
        {
            var startTime = DateTime.UtcNow;
            var timer     = new StoppableTimer(
                () =>
            {
                var elapsed        = DateTime.UtcNow.Subtract(startTime);
                var remainingItems = collection
                                     .Where(item => !taskSelector(item).IsCompleted)
                                     .ToList();
                action(elapsed, collection, remainingItems);
            },
                dueTime: 0,
                period: (int)period.TotalMilliseconds);

            using (timer)
            {
                var result = await Task.WhenAll(collection.Select(item => taskSelector(item)));

                await timer.StopAsync();

                // report once at the end
                action(DateTime.UtcNow.Subtract(startTime), collection, CollectionUtilities.EmptyArray <TItem>());
                return(result);
            }
        }