private async Task <bool> PushBucketAsync(BillingUsageBucket bucket, CancellationToken cancellationToken) { try { var records = await bucket.GetRecordsAsync(cancellationToken); if (records == null || records.Count <= 0) { BillingEventSource.Current.Warning(BillingEventSource.EmptyTrackingId, this, nameof(this.PushBucketAsync), OperationStates.Dropped, $"Bucket '{bucket.BucketKey}' has no records."); return(true); } var batchId = Guid.NewGuid(); var pushAny = 0; // Push to table Func <IEnumerable <ResourceUsageRecord>, Guid, Task> pushBatchFunc = async(batch, id) => { bool succeed = await this.PushUsageBatchAsync(batch, id, cancellationToken); if (succeed) { Interlocked.Exchange(ref pushAny, 1); } }; await this.ParallelPushAsync(records, batchId, pushBatchFunc); if (pushAny > 0) { // Notify to queue await NotifyPushAsync(batchId, cancellationToken); await bucket.ClearAsync(); } return(pushAny > 0); } catch (Exception ex) { BillingEventSource.Current.ErrorException(BillingEventSource.EmptyTrackingId, this, nameof(this.PushBucketAsync), OperationStates.Failed, string.Empty, ex); return(false); } }