// Begin counting available requests. internal async Task StartQuotaCount(SheetsService sheetsService, string sessionsSpreadsheetId, CancellationToken cancellationToken) { // Await limiter repository await SessionRequestsLimiter._limiterSemaphore.WaitAsync(); try { // Throw if cancellation has been requested after semaphore has been released cancellationToken.ThrowIfCancellationRequested(); // Engage initialization mode to await deadlock when obtaining initial available quota this._initializationMode = true; this._stopped = false; await Task.Run(() => this.AvailableQuota = SessionsRepository.RetrieveInitialAvailableQuota(sheetsService, sessionsSpreadsheetId)); } // Finally release limiter repository finally { this._initializationMode = false; SessionRequestsLimiter._limiterSemaphore.Release(); } // Do not await #pragma warning disable CS4014 // Do not await task to return on operational and still maintain data consistency. Task.Run(async() => { while (!this._stopped) { await Task.Delay(1000, cancellationToken); if ((this.AvailableQuota + SessionRequestsLimiter.QuotaRequestsPerSec) > SessionRequestsLimiter.QuotaRequestsLimit) { this.AvailableQuota = SessionRequestsLimiter.QuotaRequestsLimit; } else { this.AvailableQuota += SessionRequestsLimiter.QuotaRequestsPerSec; } } }, cancellationToken); #pragma warning restore CS4014 }