예제 #1
0
        /// <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);
            }
        }
예제 #2
0
        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();
            }
        }