private async void TryFinishStreamRender(IReportableStream stream)
        {
            if (!stream.IsCompleted)
            {
                return;
            }

            stream.StreamModified  -= OnStreamModified;
            stream.StreamCompleted -= OnStreamCompleted;

            if (renderInProgress)
            {
                return;
            }

            await streamedContainer.Dispatcher.BeginInvoke(
                new SetEmptyStream(SetEmptyCommandStream),
                DispatcherPriority.ApplicationIdle,
                streamedContainer);

            streamedContainer = null;
            stream.Dispose();
            streamedOnAfterRender = null;
            streamedOnFinished?.Invoke();
            streamedOnFinished = null;

            _ = Task.Run(() =>
            {
                GC.Collect(3, GCCollectionMode.Optimized, false);
            });

            // Warn: This can cause freeze of an entire application
            // GC.Collect(3, GCCollectionMode.Forced, true);
        }
        public async Task <Section> StartStreamRenderAsync(IReportableStream stream, Action <Span> onAfterRender, Action onFinish)
        {
            Section itemSection = new Section();

            itemSection.Blocks.Add(new Paragraph(await StartStreamRenderToSpanAsync(stream, onAfterRender, onFinish)));
            return(itemSection);
        }
        private async Task <Span> StartStreamRenderToSpanAsync(IReportableStream stream, Action <Span> onAfterRender, Action onFinish)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (stream.IsClosed)
            {
                throw new InvalidOperationException("The text stream is already closed.");
            }

            if (streamedContainer != null)
            {
                throw new InvalidOperationException("Another stream render already in progress.");
            }

            if (stream.IsCompleted)
            {
                string allText;
                using (TextReader reader = new StreamReader(stream.Stream, Encoding.UTF8, false, 1024, true))
                {
                    allText = await reader.ReadToEndAsync();
                }

                Span container = BuildText(allText);
                stream.Dispose();
                onFinish?.Invoke();
                return(container);
            }

            stream.StreamModified  += OnStreamModified;
            stream.StreamCompleted += OnStreamCompleted;

            renderInProgress      = false;
            renderIsRequested     = false;
            streamedContainer     = new Span();
            streamedPosition      = 0;
            streamedOnAfterRender = onAfterRender;
            streamedOnFinished    = onFinish;
            return(streamedContainer);
        }
        private async Task RenderModifiedStreamAsync(IReportableStream stream)
        {
            renderInProgress  = true;
            renderIsRequested = false;
            string newText;

            using (TextReader reader = new StreamReader(stream.Stream, Encoding.UTF8, false, 1024, true))
            {
                newText = await reader.ReadToEndAsync();
            }

            await streamedContainer.Dispatcher.BeginInvoke(new RenderMethod(BuildStreamedText), DispatcherPriority.Background, newText);

            if (renderIsRequested)
            {
                // TODO: [P3] A swallowed exception
                _ = RenderModifiedStreamAsync(stream);
            }
            else
            {
                renderInProgress = false;
                TryFinishStreamRender(stream);
            }
        }
Example #5
0
 public StreamedItem(IReportableStream stream)
 {
     Stream = stream;
 }
Example #6
0
 public Task <Section> StartStreamRenderAsync(IReportableStream stream, Action <Span> onAfterRender, Action onFinish)
 {
     return(streamRenderService.StartStreamRenderAsync(stream, onAfterRender, onFinish));
 }