Пример #1
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));
        }
Пример #2
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;
            }
        }