//============================================================================================== internal Messaging.CompletionState LoadCompletionState(out int lastDatabaseId) { var isDbReady = IsDatabaseReadyAsync(CancellationToken.None).GetAwaiter().GetResult(); var ids = isDbReady ? _dataProvider.GetUnprocessedActivityIds() : Array.Empty <int>(); lastDatabaseId = ids.LastOrDefault(); var result = new Messaging.CompletionState(); // there is no unprocessed: last item is the last database id if (ids.Length <= 1) { result.LastActivityId = lastDatabaseId; return(result); } // there is only one unprocessed element if (ids.Length == 2) { result.LastActivityId = lastDatabaseId; result.Gaps = new[] { ids[ids.Length - 2] }; return(result); } // if last unprocessed and last database id does not equal, // each item is gap if (lastDatabaseId != ids[ids.Length - 2]) { // i-2 -1 // _,_,3,_,_,6,_,8,9,10,11 ,12 result.LastActivityId = lastDatabaseId; result.Gaps = ids.Take(ids.Length - 1).ToArray(); return(result); } // i-2 -1 // _,_,3,_,_,6,_,8,9,10,11,12 ,12 var continuousFrom = 0; for (var i = ids.Length - 2; i >= 1; i--) { if (ids[i] != ids[i - 1] + 1) { continuousFrom = i; break; } } result.LastActivityId = ids[continuousFrom] - 1; result.Gaps = ids.Take(continuousFrom).ToArray(); return(result); }