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)); }
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; } }
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)); }
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)); }