public async Task ClearAsync() { int count = await Table.CreateQuery <DataItem>().CountAsync(); var batch = new TableBatchOperation(); for (int i = count - 1; i >= 0; i--) { batch.RemoveAt(i); } await Table.ExecuteBatchAsync(batch); }
public void TableBatchLockToPartitionKey() { TableBatchOperation batch = new TableBatchOperation(); batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo"))); try { batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2"))); Assert.Fail(); } catch (ArgumentException) { // no op } catch (Exception) { Assert.Fail(); } // should reset pk lock batch.RemoveAt(0); batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2"))); try { batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2"))); } catch (ArgumentException) { Assert.Fail(); } catch (Exception) { Assert.Fail(); } }
public void TableBatchLockToPartitionKey() { TableBatchOperation batch = new TableBatchOperation(); batch.Add(TableOperation.Insert(GenerateRandomEntity("foo"))); try { batch.Add(TableOperation.Insert(GenerateRandomEntity("foo2"))); Assert.Fail(); } catch (ArgumentException) { // no op } catch (Exception) { Assert.Fail(); } // should reset pk lock batch.RemoveAt(0); batch.Add(TableOperation.Insert(GenerateRandomEntity("foo2"))); try { batch.Add(TableOperation.Insert(GenerateRandomEntity("foo2"))); } catch (ArgumentException) { Assert.Fail(); } catch (Exception) { Assert.Fail(); } }
/// <summary> /// Removes a batch of items from the table. /// </summary> /// <param name="table">CloudTable instance.</param> /// <param name="tbo">TableBatchOperations instance.</param> internal async Task <int> RemoveItemsAsync(CloudTable table, TableBatchOperation tbo) { if (null == table) { throw new ArgumentNullException("Argument is null", nameof(table)); } if (null == tbo) { throw new ArgumentNullException("Argument is null", nameof(tbo)); } int count = 0; const int maxRetryCount = 5; int retry = maxRetryCount; do { // Reset count in case the while was retried. count = 0; try { TableRequestOptions tro = new TableRequestOptions() { MaximumExecutionTime = TimeSpan.FromSeconds(60), ServerTimeout = TimeSpan.FromSeconds(5), RetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 3) }; // Ensure that the batch isn't empty, if it is, return the count. if (0 == tbo.Count) { break; } // Execute the batch operations. IList <TableResult> results = results = await table.ExecuteBatchAsync(tbo, tro, null, this._token); if ((null != results) && (results.Count > 0)) { int itemCount = 0, failureCount = 0; foreach (TableResult result in results) { itemCount++; if (false == ((HttpStatusCode)result.HttpStatusCode).IsSuccessCode()) { failureCount++; } } ServiceEventSource.Current.Trace($"Removed {itemCount - failureCount} of {itemCount} items from {table.Name}."); count = itemCount - failureCount; } } catch (StorageException ex) { // ResourceNotFound is returned when one of the batch items isn't found. Need to remove it and try again. if (ex.RequestInformation?.ExtendedErrorInformation?.ErrorCode.Contains("ResourceNotFound") ?? false) { // Get the index of the item within the batch. if (false == int.TryParse( ex.RequestInformation?.ExtendedErrorInformation?.ErrorMessage.Split(':')[0], out int index)) { ServiceEventSource.Current.Trace("Unknown index, setting to 0", table.Name); index = 0; } if (index < tbo.Count) { ServiceEventSource.Current.Trace($"StorageException: ResourceNotFound for item {index}", table.Name); await Task.Delay(500); tbo.RemoveAt(index); retry--; } else { ServiceEventSource.Current.Trace("Abandoning batch.", table.Name); break; } } else { ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, ex.StackTrace); break; } } } while ((retry > 0) && (retry < maxRetryCount)); // Only retry if we hit a retryable exception or run out of retries. return(count); }