Progress leaves some residue output with `HideCompleted(true)`
Information
- OS: Windows
- Version: 0.38.0
- Terminal: VS Code, cmd, Terminal
Describe the bug
When reporting progress with HideCompleted(true), once all operations have completed, some residue output remains. This seems to include empty lines for each progress line, as well as a random . character.
I'm writing additional output before and after the progress so this issue makes the layout look a bit ugly.
Here's a video:
https://user-images.githubusercontent.com/1935960/112225742-ebabeb00-8c35-11eb-87c0-cce2bcafd3c0.mp4
To Reproduce
Code used in the video above:
using System.Threading;
using System.Linq;
using System.Threading.Tasks;
using System;
using Spectre.Console;
namespace SpectreTest
{
class Program
{
static async Task Main(string[] args)
{
var random = new Random();
using var semaphore = new SemaphoreSlim(5, 5);
await AnsiConsole.Progress().HideCompleted(true).StartAsync(async ctx =>
{
await Task.WhenAll(
Enumerable.Range(0, 50).Select(async i =>
{
await semaphore.WaitAsync();
var progress = ctx.AddTask("Task " + i);
await Task.Delay(random.Next(100, 3000));
progress.Value = progress.MaxValue;
semaphore.Release();
})
);
});
}
}
}
Expected behavior
Once the progress has completed with HideCompleted(true), I would expect the console window to return to its previous state before the progress started (i.e. as if progress reporting never happened).
@Tyrrrz Not sure what's going on here, but you shouldn't need a semaphore since things aren't updated when you update the tasks; they're updated on a background thread. Will take a look at this later this week.
@patriksvensson Thanks for the reply!
The semaphore is not crucial for reproduction of the bug. It's just used in the example to limit the number of tasks active at the same time. This is similar to how I'm using it in my application, where I have ~100 tasks but only ~5 running at a time.
Here's another shot without using semaphore:
using System.Threading;
using System.Linq;
using System.Threading.Tasks;
using System;
using Spectre.Console;
namespace SpectreTest
{
class Program
{
static async Task Main(string[] args)
{
var random = new Random();
await AnsiConsole.Progress().HideCompleted(true).StartAsync(async ctx =>
{
await Task.WhenAll(
Enumerable.Range(0, 50).Select(async i =>
{
var progress = ctx.AddTask("Task " + i);
await Task.Delay(random.Next(100, 3000));
progress.Value = progress.MaxValue;
})
);
});
}
}
}
https://user-images.githubusercontent.com/1935960/112227402-49d9cd80-8c38-11eb-8ef4-298e76749a5d.mp4
Note that there is apparently some output from one of the previous runs before dotnet run that didn't get removed by cls. Regardless, you can see the dot is still there, along with a lot of empty space. Also, not sure what's going on here, but it looks like maybe the tasks do not get hidden if they are completed too fast?
Being the developer responsible for the HideCompleted(true) option, I can confirm that when all the tasks are completed, some dirt is left in the console. I noticed this behaviour while developing the option and I even somehow "documented" it in a Unit Test which did not make it to the final cut (from https://github.com/spectresystems/spectre.console/commit/1c769c661008d78efc4c66e2af4203ac966c5cea#diff-14e77f7785ea266d74e17b75fc43a7e4d774ffbe80c2c1cf9d7fd6eb12062425R214):

Back then I did not have time to investigate and the presence of the dirt in the session did not bother me much so I left it at that. I don't know when I'll have time to try and figure out what is going on, so if anybody wants to step in I won't feel offended ;-)
@lstefano71 The ... ellipsis is part of a table bug I've been meaning to fix for quite some time. I'll make this a priority and hopefully, this will fix itself.