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); }
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); }