diff --git a/sdk/Managed/src/Microsoft.WindowsAzure.MobileServices/Table/Sync/Queue/Actions/PushAction.cs b/sdk/Managed/src/Microsoft.WindowsAzure.MobileServices/Table/Sync/Queue/Actions/PushAction.cs index d6d71fa82..0f97b2372 100644 --- a/sdk/Managed/src/Microsoft.WindowsAzure.MobileServices/Table/Sync/Queue/Actions/PushAction.cs +++ b/sdk/Managed/src/Microsoft.WindowsAzure.MobileServices/Table/Sync/Queue/Actions/PushAction.cs @@ -132,104 +132,104 @@ private async Task ExecuteAllOperationsAsync(OperationBatch batch) // keep taking out operations and executing them until queue is empty or operation finds the bookmark or batch is aborted while (operation != null) { - bool success = await this.ExecuteOperationAsync(operation, batch); - - if (batch.AbortReason.HasValue) + using (await this.OperationQueue.LockItemAsync(operation.ItemId, this.CancellationToken)) { - break; - } + bool success = await this.ExecuteOperationAsync(operation, batch); - if (success) - { - // we successfuly executed an operation so remove it from queue - await this.OperationQueue.DeleteAsync(operation.Id, operation.Version); - } + if (batch.AbortReason.HasValue) + { + break; + } - // get next operation - operation = await this.OperationQueue.PeekAsync(operation.Sequence, this.tableKind, this.tableNames); + if (success) + { + // we successfuly executed an operation so remove it from queue + await this.OperationQueue.DeleteAsync(operation.Id, operation.Version); + } + + // get next operation + operation = await this.OperationQueue.PeekAsync(operation.Sequence, this.tableKind, this.tableNames); + } } } private async Task ExecuteOperationAsync(MobileServiceTableOperation operation, OperationBatch batch) { - using (await this.OperationQueue.LockItemAsync(operation.ItemId, this.CancellationToken)) + if (operation.IsCancelled || this.CancellationToken.IsCancellationRequested) { - if (operation.IsCancelled || this.CancellationToken.IsCancellationRequested) - { - return false; - } + return false; + } - operation.Table = await this.context.GetTable(operation.TableName); - await this.LoadOperationItem(operation, batch); + operation.Table = await this.context.GetTable(operation.TableName); + await this.LoadOperationItem(operation, batch); - if (this.CancellationToken.IsCancellationRequested) - { - return false; - } + if (this.CancellationToken.IsCancellationRequested) + { + return false; + } - await TryUpdateOperationState(operation, MobileServiceTableOperationState.Attempted, batch); + await TryUpdateOperationState(operation, MobileServiceTableOperationState.Attempted, batch); - // strip out system properties before executing the operation - operation.Item = MobileServiceSyncTable.RemoveSystemPropertiesKeepVersion(operation.Item); + // strip out system properties before executing the operation + operation.Item = MobileServiceSyncTable.RemoveSystemPropertiesKeepVersion(operation.Item); - JObject result = null; - Exception error = null; - try - { - result = await batch.SyncHandler.ExecuteTableOperationAsync(operation); - } - catch (Exception ex) - { - error = ex; - } - - if (error != null) - { - await TryUpdateOperationState(operation, MobileServiceTableOperationState.Failed, batch); + JObject result = null; + Exception error = null; + try + { + result = await batch.SyncHandler.ExecuteTableOperationAsync(operation); + } + catch (Exception ex) + { + error = ex; + } - if (TryAbortBatch(batch, error)) - { - // there is no error to save in sync error and no result to capture - // this operation will be executed again next time the push happens - return false; - } - } + if (error != null) + { + await TryUpdateOperationState(operation, MobileServiceTableOperationState.Failed, batch); - // save the result if ExecuteTableOperation did not throw - if (error == null && result.IsValidItem() && operation.CanWriteResultToStore) + if (TryAbortBatch(batch, error)) { - await TryStoreOperation(() => this.Store.UpsertAsync(operation.TableName, result, fromServer: true), batch, Resources.SyncStore_FailedToUpsertItem); + // there is no error to save in sync error and no result to capture + // this operation will be executed again next time the push happens + return false; } - else if (error != null) + } + + // save the result if ExecuteTableOperation did not throw + if (error == null && result.IsValidItem() && operation.CanWriteResultToStore) + { + await TryStoreOperation(() => this.Store.UpsertAsync(operation.TableName, result, fromServer: true), batch, Resources.SyncStore_FailedToUpsertItem); + } + else if (error != null) + { + HttpStatusCode? statusCode = null; + string rawResult = null; + var iox = error as MobileServiceInvalidOperationException; + if (iox != null && iox.Response != null) { - HttpStatusCode? statusCode = null; - string rawResult = null; - var iox = error as MobileServiceInvalidOperationException; - if (iox != null && iox.Response != null) - { - statusCode = iox.Response.StatusCode; - Tuple content = await MobileServiceTable.ParseContent(iox.Response, this.client.SerializerSettings); - rawResult = content.Item1; - result = content.Item2.ValidItemOrNull(); - } - var syncError = new MobileServiceTableOperationError(operation.Id, - operation.Version, - operation.Kind, - statusCode, - operation.TableName, - operation.Item, - rawResult, - result) - { - TableKind = this.tableKind, - Context = this.context - }; - await batch.AddSyncErrorAsync(syncError); + statusCode = iox.Response.StatusCode; + Tuple content = await MobileServiceTable.ParseContent(iox.Response, this.client.SerializerSettings); + rawResult = content.Item1; + result = content.Item2.ValidItemOrNull(); } - - bool success = error == null; - return success; + var syncError = new MobileServiceTableOperationError(operation.Id, + operation.Version, + operation.Kind, + statusCode, + operation.TableName, + operation.Item, + rawResult, + result) + { + TableKind = this.tableKind, + Context = this.context + }; + await batch.AddSyncErrorAsync(syncError); } + + bool success = error == null; + return success; } private async Task TryUpdateOperationState(MobileServiceTableOperation operation, MobileServiceTableOperationState state, OperationBatch batch)