private static IEnumerable <AsyncResultOr <string> > ProcessRequest(ElmahCore.ErrorLog log, HttpContext context, Func <AsyncCallback> getAsyncCallback, Format format, int maxDownloadCount) { var response = context.Response; foreach (var text in format.Header()) { yield return(AsyncResultOr.Value(text)); } var lastBeatTime = DateTime.Now; var errorEntryList = new List <ErrorLogEntry>(PageSize); var downloadCount = 0; for (var pageIndex = 0; ; pageIndex++) { var ar = log.BeginGetErrors(pageIndex, PageSize, errorEntryList, getAsyncCallback(), null); yield return(AsyncResultOr.InsteadOf <string>(ar)); var total = log.EndGetErrors(ar); var count = errorEntryList.Count; if (maxDownloadCount > 0) { var remaining = maxDownloadCount - (downloadCount + count); if (remaining < 0) { count += remaining; } } foreach (var entry in format.Entries(errorEntryList, 0, count, total)) { yield return(AsyncResultOr.Value(entry)); } downloadCount += count; response.Body.Flush(); // // Done if either the end of the list (no more errors found) or // the requested limit has been reached. // if (count == 0 || downloadCount == maxDownloadCount) { if (count > 0) { foreach (var entry in format.Entries(new ErrorLogEntry[0], total)) // Terminator { yield return(AsyncResultOr.Value(entry)); } } break; } // // Poll whether the client is still connected so data is not // unnecessarily sent to an abandoned connection. This check is // only performed at certain intervals. // if (DateTime.Now - lastBeatTime > BeatPollInterval) { lastBeatTime = DateTime.Now; } // // Fetch next page of results. // errorEntryList.Clear(); } }