Ejemplo n.º 1
0
        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();
            }
        }