public void Dispose() { if (Interlocked.CompareExchange(ref _isDisposed, 1, 0) != 0) { return; } // make sure background task is stopped before we clean up _displayProgressEvent.Set(); _displayProgress.Wait(); // update one last time - needed because background task might have // been already in progress before Dispose was called and it might // have been running for a very long time due to poor performance // of System.Console UpdateProgress(); //make sure we pop all pending messages while (_stickyMessages.TryDequeue(out var m)) { WriteConsoleLine(m); } if (this.EndTime == null) { this.EndTime = DateTime.Now; } var openDescendantsPadding = (_visibleDescendants * 2); if (this.Options.EnableTaskBarProgress) { TaskbarProgress.SetState(TaskbarProgress.TaskbarStates.NoProgress); } try { var moveDown = 0; var currentWindowTop = Console.WindowTop; if (currentWindowTop != _originalWindowTop) { var x = Math.Max(0, Math.Min(2, currentWindowTop - _originalWindowTop)); moveDown = _originalCursorTop + x; } else { moveDown = _originalCursorTop + 2; } Console.CursorVisible = true; Console.SetCursorPosition(0, openDescendantsPadding + moveDown); } // This is bad and I should feel bad, but i rather eat pbar exceptions in productions then causing false negatives catch { } Console.WriteLine(); _timer?.Dispose(); _timer = null; foreach (var c in this.Children) { c.Dispose(); } }
protected override void DisplayProgress() { if (_isDisposed) { return; } Console.CursorVisible = false; var indentation = new[] { new Indentation(this.ForeGroundColor, true) }; var mainPercentage = this.Percentage; lock (Lock) { Console.ForegroundColor = this.ForeGroundColor; void TopHalf() { ProgressBarTopHalf(mainPercentage, this.Options.ProgressCharacter, this.Options.BackgroundCharacter, this.Options.BackgroundColor, indentation, this.Options.ProgressBarOnBottom ); } if (this.Options.ProgressBarOnBottom) { Console.CursorLeft = 0; ProgressBarBottomHalf(mainPercentage, this._startDate, null, this.Message, indentation, this.Options.ProgressBarOnBottom); if (!IsWindows) { Console.CursorTop = Console.CursorTop + 1; } Console.CursorLeft = 0; TopHalf(); } else { Console.CursorLeft = 0; TopHalf(); if (!IsWindows) { Console.CursorTop = Console.CursorTop + 1; } Console.CursorLeft = 0; ProgressBarBottomHalf(mainPercentage, this._startDate, null, this.Message, indentation, this.Options.ProgressBarOnBottom); } if (this.Options.EnableTaskBarProgress) { TaskbarProgress.SetValue(mainPercentage, 100); } DrawChildren(this.Children, indentation); ResetToBottom(); Console.CursorLeft = 0; Console.CursorTop = _originalCursorTop; Console.ForegroundColor = _originalColor; if (!(mainPercentage >= 100)) { return; } _timer?.Dispose(); _timer = null; } }
private void UpdateProgress() { var mainPercentage = this.Percentage; if (this.Options.EnableTaskBarProgress) { TaskbarProgress.SetValue(mainPercentage, 100); } // write queued console messages, displayprogress is signaled straight after but // just in case make sure we never write more then 5 in a display progress tick for (var i = 0; i < 5 && _stickyMessages.TryDequeue(out var m); i++) { WriteConsoleLine(m); } if (Console.IsOutputRedirected) { return; } Console.CursorVisible = false; var indentation = new[] { new Indentation(this.ForeGroundColor, true) }; var cursorTop = _originalCursorTop; Console.ForegroundColor = this.ForeGroundColor; void TopHalf() { ProgressBarTopHalf(mainPercentage, this.Options.ProgressCharacter, this.Options.BackgroundCharacter, this.Options.BackgroundColor, indentation, this.Options.ProgressBarOnBottom ); } if (this.Options.ProgressBarOnBottom) { ProgressBarBottomHalf(mainPercentage, this._startDate, null, this.Message, indentation, this.Options.ProgressBarOnBottom); Console.SetCursorPosition(0, ++cursorTop); TopHalf(); } else { TopHalf(); Console.SetCursorPosition(0, ++cursorTop); ProgressBarBottomHalf(mainPercentage, this._startDate, null, this.Message, indentation, this.Options.ProgressBarOnBottom); } DrawChildren(this.Children, indentation, ref cursorTop); ResetToBottom(ref cursorTop); Console.SetCursorPosition(0, _originalCursorTop); Console.ForegroundColor = _originalColor; if (!(mainPercentage >= 100)) { return; } _timer?.Dispose(); _timer = null; }
public ProgressBar(int maxTicks, string message, ProgressBarOptions options = null) : base(maxTicks, message, options) { _writeMessageToConsole = this.Options.WriteQueuedMessage ?? DefaultConsoleWrite; _startedRedirected = Console.IsOutputRedirected; try { _originalCursorTop = Console.CursorTop; _originalWindowTop = Console.WindowTop; _originalWindowHeight = Console.WindowHeight + _originalWindowTop; _originalColor = Console.ForegroundColor; } catch { _startedRedirected = true; } if (!_startedRedirected) { Console.CursorVisible = false; } if (this.Options.EnableTaskBarProgress) { TaskbarProgress.SetState(TaskbarProgress.TaskbarStates.Normal); } if (this.Options.DisplayTimeInRealTime) { _timer = new Timer((s) => OnTimerTick(), null, 500, 500); } else //draw once { _timer = new Timer((s) => { _timer.Dispose(); DisplayProgress(); }, null, 0, 1000); } _displayProgressEvent = new AutoResetEvent(false); _displayProgress = Task.Run(() => { while (_isDisposed == 0) { if (!_displayProgressEvent.WaitOne(TimeSpan.FromSeconds(10))) { continue; } if (_isDisposed > 0) { return; } try { UpdateProgress(); } catch { //don't want to crash background thread } } }); }