/// <summary> /// Read data entries and their corresponding eTags from the Azure table. /// </summary> /// <param name="filter">Filter string to use for querying the table and filtering the results.</param> /// <returns>Enumeration of entries in the table which match the query condition.</returns> public async Task <IEnumerable <Tuple <T, string> > > ReadTableEntriesAndEtagsAsync(string filter) { const string operation = "ReadTableEntriesAndEtags"; var startTime = DateTime.UtcNow; try { TableQuery <T> cloudTableQuery = filter == null ? new TableQuery <T>() : new TableQuery <T>().Where(filter); try { Func <Task <List <T> > > executeQueryHandleContinuations = async() => { TableQuerySegment <T> querySegment = null; var list = new List <T>(); //ExecuteSegmentedAsync not supported in "WindowsAzure.Storage": "7.2.1" yet while (querySegment == null || querySegment.ContinuationToken != null) { querySegment = await tableReference.ExecuteQuerySegmentedAsync(cloudTableQuery, querySegment?.ContinuationToken); list.AddRange(querySegment); } return(list); }; #if !ORLEANS_TRANSACTIONS IBackoffProvider backoff = new FixedBackoff(AzureTableDefaultPolicies.PauseBetweenTableOperationRetries); List <T> results = await AsyncExecutorWithRetries.ExecuteWithRetries( counter => executeQueryHandleContinuations(), AzureTableDefaultPolicies.MaxTableOperationRetries, (exc, counter) => AzureStorageUtils.AnalyzeReadException(exc.GetBaseException(), counter, TableName, Logger), AzureTableDefaultPolicies.TableOperationTimeout, backoff); #else List <T> results = await executeQueryHandleContinuations(); #endif // Data was read successfully if we got to here return(results.Select(i => Tuple.Create(i, i.ETag)).ToList()); } catch (Exception exc) { // Out of retries... var errorMsg = $"Failed to read Azure storage table {TableName}: {exc.Message}"; if (!AzureStorageUtils.TableStorageDataNotFound(exc)) { Logger.Warn((int)Utilities.ErrorCode.AzureTable_09, errorMsg, exc); } throw new OrleansException(errorMsg, exc); } } finally { CheckAlertSlowAccess(startTime, operation); } }