Пример #1
0
        private Task <IReadOnlyCollection <KeyValuePair <CellFeed, IAggregateProgress> > > UpdateFeedBatchesAsync(
            List <List <SheetCellInfo> > cellGroups,
            IEnumerable <CellFeed> mappingFeeds,
            string cellsFeedUrl,
            string batchUrl,
            IAggregateProgress progress,
            CancellationToken cancellationToken)
        {
            return(Task.Run <IReadOnlyCollection <KeyValuePair <CellFeed, IAggregateProgress> > >(
                       () =>
            {
                var cellsJoin = mappingFeeds.Zip(cellGroups, (mappingFeed, cellsGroup) =>
                                                 from feedCell in mappingFeed.Entries.Cast <CellEntry>()
                                                 from cell in cellsGroup
                                                 where feedCell.Row == cell.Row && feedCell.Column == cell.Column
                                                 select new { Cell = cell, FeedCell = feedCell });
                var updatingProgresses = progress.CreateParallelProgresses(cellGroups.Select(g => (double)g.Count).ToList());

                var batches = cellsJoin.Zip(updatingProgresses, (cells, p) =>
                {
                    var updateFeed = new CellFeed(new Uri(cellsFeedUrl), Service)
                    {
                        Batch = batchUrl
                    };

                    foreach (var pair in cells)
                    {
                        updateFeed.Entries.Add(pair.Cell.BatchUpdateEntry(pair.FeedCell));
                    }

                    cancellationToken.ThrowIfCancellationRequested();

                    return new KeyValuePair <CellFeed, IAggregateProgress>(updateFeed, p);
                });

                return batches.ToList();
            }, cancellationToken));
        }
        public static Task <TEntry> InsertItemAsync <TEntry>(this SpreadsheetsService service, string feedUri, TEntry item, IAggregateProgress progress = null, CancellationToken cancellationToken = default(CancellationToken))
            where TEntry : AtomEntry
        {
            var userData = new object();

            service.InsertAsync(new Uri(feedUri), item, userData);

            return(QueryEntryAsync <TEntry>(service, userData, progress, cancellationToken));
        }
        public static Task DeleteItemAsync <TEntry>(this SpreadsheetsService service, TEntry item, IAggregateProgress progress = null, CancellationToken cancellationToken = default(CancellationToken))
            where  TEntry : AtomEntry
        {
            var userData = new object();

            service.DeleteAsync(item, true, userData);

            return(QueryEntryAsync <TEntry>(service, userData, progress, cancellationToken));
        }
        public static async Task <TFeed> BatchFeedAsync <TFeed>(this SpreadsheetsService service, TFeed feed, int attempts, IAggregateProgress progress = null, CancellationToken cancellationToken = default(CancellationToken))
            where TFeed : AtomFeed
        {
            try
            {
                var userData = new object();

                service.BatchAsync(feed, new Uri(feed.Batch), userData);

                return(await QueryFeedAsync <TFeed>(service, userData, progress, cancellationToken));
            }
            catch (TimeoutException)
            {
                //Retrying if timeout.
                attempts--;

                if (attempts > 0)
                {
                    //Then retry.
                }
                else
                {
                    throw;
                }
            }

            return(await BatchFeedAsync(service, feed, attempts, progress, cancellationToken));
        }
        private static Task <TResult> GetFeedAsync <TResult, TQuery>(SpreadsheetsService service, TQuery query, IAggregateProgress progress, CancellationToken cancellationToken)
            where TQuery : FeedQuery
            where TResult : AtomFeed
        {
            var userData = new object();

            service.QueryFeedAync(query.Uri, query.ModifiedSince, userData);

            return(QueryFeedAsync <TResult>(service, userData, progress, cancellationToken));
        }
 public static Task <ListFeed> GetFeedAsync(this SpreadsheetsService service, ListQuery query, IAggregateProgress progress = null, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(GetFeedAsync <ListFeed, ListQuery>(service, query, progress, cancellationToken));
 }
        private static Task <TResult> ExecuteAsync <TResult>(SpreadsheetsService service, object userData, IAggregateProgress progress, CancellationToken cancellationToken, Func <AsyncOperationCompletedEventArgs, TResult> getResult)
            where TResult : AtomBase
        {
            var taskSource = new TaskCompletionSource <TResult>();

            AsyncOperationProgressEventHandler progressHandler = null;

            if (progress != null)
            {
                progressHandler = (sender, eventArgs) =>
                {
                    if (eventArgs.UserState == userData)
                    {
                        progress.Report(eventArgs.ProgressPercentage);
                    }
                };

                service.AsyncOperationProgress += progressHandler;
            }

            AsyncOperationCompletedEventHandler evnetHandler = null;

            evnetHandler = (sender, eventArgs) =>
            {
                if (eventArgs.UserState == userData)
                {
                    service.AsyncOperationCompleted -= evnetHandler;
                    if (progress != null)
                    {
                        progress.Report(100);
                        service.AsyncOperationProgress -= progressHandler;
                    }

                    if (eventArgs.Error != null)
                    {
                        taskSource.TrySetException(eventArgs.Error);
                    }
                    else
                    {
                        taskSource.TrySetResult(getResult(eventArgs));
                    }
                }
            };

            service.AsyncOperationCompleted += evnetHandler;

            cancellationToken.Register(() =>
            {
                if (taskSource.TrySetCanceled())
                {
                    service.AsyncOperationCompleted -= evnetHandler;
                    if (progress != null)
                    {
                        service.AsyncOperationProgress -= progressHandler;
                    }

                    service.CancelAsync(userData);
                }
            });

            return(taskSource.Task);
        }
 private static Task <TResult> QueryEntryAsync <TResult>(SpreadsheetsService service, object userData, IAggregateProgress progress, CancellationToken cancellationToken)
     where TResult : AtomEntry
 {
     return(ExecuteAsync(service, userData, progress, cancellationToken, args => (TResult)args.Entry));
 }
Пример #9
0
        private async Task PushCellsAsync <TModel>(WorksheetEntry worksheet, ResGroupModel <TModel> group, SemaphoreSlim semaphore, IAggregateProgress progress, CancellationToken cancellationToken)
            where TModel : IRowModel
        {
            var progresses       = progress.CreateParallelProgresses(0.2, 0.8);
            var mappingProgress  = progresses[0];
            var updatingProgress = progresses[1];



            var cellFeed = await Service.GetFeedAsync(worksheet.GetCellsQuery(), cancellationToken : cancellationToken);

            string cellsFeedUrl = cellFeed.Self;
            string batchUrl     = cellFeed.Batch;

            var resCells = await CreateSheetCellInfos(group, cancellationToken);

            var cellGroups = Devide(resCells, MaxBatchSize);

            var mappingTasks = (await MapFeedBatchesAsync(cellGroups, cellsFeedUrl, batchUrl, mappingProgress, cancellationToken))
                               .Select(async kvp =>
            {
                var mappingFeed = kvp.Key;
                var p           = kvp.Value;

                await semaphore.WaitAsync(cancellationToken);

                try
                {
                    return(await Service.BatchFeedAsync(mappingFeed, TimeOutAttemptsCount, p, cancellationToken));
                }
                finally
                {
                    semaphore.Release();
                }
            });

            //Mapping cells.
            List <CellFeed> mappingFeeds = new List <CellFeed>(cellGroups.Count);

            foreach (var mappingTask in mappingTasks)
            {
                mappingFeeds.Add(await mappingTask);
            }

            //Updating cells.
            var updatingTasks = (await UpdateFeedBatchesAsync(cellGroups, mappingFeeds, cellsFeedUrl, batchUrl, updatingProgress, cancellationToken))
                                .Select(async kvp =>
            {
                var updateFeed = kvp.Key;
                var p          = kvp.Value;

                await semaphore.WaitAsync(cancellationToken);

                try
                {
                    return(await Service.BatchFeedAsync(updateFeed, TimeOutAttemptsCount, p, cancellationToken));
                }
                finally
                {
                    semaphore.Release();
                }
            });

            foreach (var updatingTask in updatingTasks)
            {
                await updatingTask;
            }
        }
Пример #10
0
        private async Task <ResGroupModel <TModel> > GetGroupAsync <TModel>(WorksheetEntry worksheet, SemaphoreSlim semaphore, IAggregateProgress progress, CancellationToken cancellationToken)
            where TModel : IRowModel, new()
        {
            uint rowsPerBatch = MaxReadBatchSize / worksheet.Cols;

            IEnumerable <uint> batchStartIndexes = Enumerable.Range(0, (int)(worksheet.Rows / rowsPerBatch + 1)).Select(batchIndex => (uint)(batchIndex * rowsPerBatch + 1));

            var cellsQueries = batchStartIndexes.Select(rowIndex =>
            {
                var cellsQuery        = worksheet.GetCellsQuery();
                cellsQuery.MinimumRow = rowIndex;
                cellsQuery.MaximumRow = rowIndex + rowsPerBatch;
                if (cellsQuery.MaximumRow > worksheet.Rows)
                {
                    cellsQuery.MaximumRow = worksheet.Rows;
                }

                return(cellsQuery);
            }).ToList();

            var progresses = progress.CreateParallelProgresses(cellsQueries.Select(cq => (double)cq.MaximumRow - cq.MinimumRow).ToList());

            var cellsTasks = cellsQueries.Zip(progresses, async(cellsQuery, p) =>
            {
                await semaphore.WaitAsync(cancellationToken);

                try
                {
                    var cellsFeed = await Service.GetFeedAsync(cellsQuery, p, cancellationToken);

                    return(cellsFeed.Entries.Cast <CellEntry>());
                }
                finally
                {
                    semaphore.Release();
                }
            });


            var cells = (await Task.WhenAll(cellsTasks)).SelectMany(cs => cs).ToList();

            return(await ProcessGroupAsync <TModel>(worksheet, cells, cancellationToken));
        }
Пример #11
0
        private Task <IReadOnlyCollection <KeyValuePair <CellFeed, IAggregateProgress> > > MapFeedBatchesAsync(List <List <SheetCellInfo> > cellGroups, string cellsFeedUrl, string batchUrl, IAggregateProgress progress, CancellationToken cancellationToken)
        {
            return(Task.Run <IReadOnlyCollection <KeyValuePair <CellFeed, IAggregateProgress> > >(() =>
            {
                var progresses = progress.CreateParallelProgresses(cellGroups.Select(g => (double)g.Count).ToList());

                var batches = cellGroups.Zip(progresses, (cells, p) =>
                {
                    var mappingFeed = new CellFeed(new Uri(cellsFeedUrl), Service)
                    {
                        Batch = batchUrl
                    };

                    foreach (var cellEntry in cells)
                    {
                        mappingFeed.Entries.Add(cellEntry.BatchCreateEntry(cellsFeedUrl));
                    }

                    cancellationToken.ThrowIfCancellationRequested();

                    return new KeyValuePair <CellFeed, IAggregateProgress>(mappingFeed, p);
                });

                return batches.ToList();
            }, cancellationToken));
        }