/// <summary> /// Sends the ResultsUpdated message if the number of rows has changed since last send. /// </summary> /// <param name="stateInfo"></param> private async void SendResultAvailableOrUpdated(object stateInfo = null) { ResultSet currentResultSetSnapshot = (ResultSet)MemberwiseClone(); if (LastUpdatedSummary == null) // We need to send results available message. { // Fire off results Available task and await for it complete // await(ResultAvailable?.Invoke(currentResultSetSnapshot) ?? Task.CompletedTask); ResultAvailable = null; // set this to null as we need to call ResultAvailable only once } else // We need to send results updated message. { // If there has been no change in rowCount since last update and we are not done yet then log and increase the timer duration // if (!currentResultSetSnapshot.hasCompletedRead && LastUpdatedSummary.RowCount == currentResultSetSnapshot.RowCount) { Logger.Write(TraceEventType.Warning, $"The result set:{Summary} has not made any progress in last {ResultTimerInterval} milliseconds and the read of resultset is not completed yet!"); ResultsIntervalMultiplier++; } // Fire off results updated task and await for it complete // await(ResultUpdated?.Invoke(currentResultSetSnapshot) ?? Task.CompletedTask); } // Update the LastUpdatedSummary to be the value captured in current snapshot // LastUpdatedSummary = currentResultSetSnapshot.Summary; // Setup timer for the next callback if (currentResultSetSnapshot.hasCompletedRead) { //If we have already completed reading then we are done and we do not need to send any more updates. Switch off timer. // resultsTimer.Change(Timeout.Infinite, Timeout.Infinite); } else { resultsTimer.Change(ResultTimerInterval, Timeout.Infinite); } }
private async Task SendCurrentResults() { try { // Wait to acquire the sendResultsSemphore before proceeding, as we want only one instance of this method executing at any given time. // sendResultsSemphore.Wait(); ResultSet currentResultSetSnapshot = (ResultSet)MemberwiseClone(); if (LastUpdatedSummary == null) // We need to send results available message. { // Fire off results Available task and await it // await(ResultAvailable?.Invoke(currentResultSetSnapshot) ?? Task.CompletedTask); } else if (LastUpdatedSummary.Complete) // If last result summary sent had already set the Complete flag { // We do not need to do anything except that make sure that RowCount has not update since last send. Debug.Assert(LastUpdatedSummary.RowCount == currentResultSetSnapshot.RowCount, $"Already reported rows should be equal to current RowCount, if had already sent completion flag as set in last message, countReported:{LastUpdatedSummary.RowCount}, current total row count: {currentResultSetSnapshot.RowCount}, row count override: {currentResultSetSnapshot.rowCountOverride}, this.rowCountOverride: {this.rowCountOverride} and this.RowCount: {this.RowCount}, LastUpdatedSummary: {LastUpdatedSummary}"); } else // We need to send results updated message. { // Previously reported rows should be less than or equal to current number of rows about to be reported // Debug.Assert(LastUpdatedSummary.RowCount <= currentResultSetSnapshot.RowCount, $"Already reported rows should less than or equal to current total RowCount, countReported:{LastUpdatedSummary.RowCount}, current total row count: {currentResultSetSnapshot.RowCount}, row count override: {currentResultSetSnapshot.rowCountOverride}, this.rowCountOverride: {this.rowCountOverride} and this.RowCount: {this.RowCount}, LastUpdatedSummary: {LastUpdatedSummary}"); // If there has been no change in rowCount since last update and we have not yet completed read then log and increase the timer duration // if (!currentResultSetSnapshot.hasCompletedRead && LastUpdatedSummary.RowCount == currentResultSetSnapshot.RowCount) { Logger.Write(TraceEventType.Warning, $"The result set:{Summary} has not made any progress in last {ResultTimerInterval} milliseconds and the read of this result set is not yet complete!"); ResultsIntervalMultiplier++; } // Fire off results updated task and await it // await(ResultUpdated?.Invoke(currentResultSetSnapshot) ?? Task.CompletedTask); } // Update the LastUpdatedSummary to be the value captured in current snapshot // LastUpdatedSummary = currentResultSetSnapshot.Summary; // Setup timer for the next callback // if (currentResultSetSnapshot.hasCompletedRead) { // If we have already completed reading then we are done and we do not need to send any more updates. Switch off timer. // resultsTimer.Change(Timeout.Infinite, Timeout.Infinite); } else { // If we have not yet completed reading then set the timer so this method gets called again after ResultTimerInterval milliseconds // resultsTimer.Change(ResultTimerInterval, Timeout.Infinite); } } finally { // Release the sendResultsSemphore so the next invocation gets unblocked // sendResultsSemphore.Release(); } }