Properly locking the console in async code
I made an async progress bar which sits at the bottom of the console. It still needs tweaking, but I’m running into issues truly locking the console during the specific moment that the progress bar is being written to the bottom of the screen.
In order to restore the initial cursor position after updating the progress bar, I’m storing the cursor position before it to the bottom of the console. However, it seems that the console is still able to be written to during the “locked” portion of the task. This causes lines to be overwritten, because the stored cursor position is no longer accurate. How do I force a true lock in this case?
12 Replies
I don't see where you're "locking" the console at all.
Also I don't know why this would be async.
@mtreit I was trying to add a lock with this, maybe that’s not the correct way?
Trying to make it async so that I can have a progress bar that updates on a task running asynchronously while other things may be running and outputting to the console at the same time. Hence trying to make it just a bar at the bottom.
That will in theory prevent other code from calling IncrementProgressBar until they acquire the semaphore. It doesn't prevent at all other code from writing to the console.
@mtreit ohhhhhhhh so I was thinking of it backwards, then. Thank you for the clarification! Sounds like perhaps I need to make a wrapper function for writing to the console that uses a semaphore slim and utilize that for any writing to console?
That would be an approach that is much more likely to work, yes.
Thank you! That really clears things up. I’m quite new to async code in general, so sometimes I get things a bit jumbled up.
I'm not sure why you are using async at all to be honest.
Unless it's just for learning purposes.
@mtreit no it is not for learning purposes. i may no longer need it to be asynchronous now that I see I had the locking backwards… I’ll see what it ends up looking like when i rework this.
@mtreit I think I have something working now, thanks to your pointers. Found out I can lock on
Console.Out
directly, which made things far simpler. Apparently with the move to .NET Core this feature got originally removed in favor of private locking objects, but it was added back in due to the common use case of needing to change the console color in a thread-safe manner. I’m sure this could be more efficient, but it works for now at least.
hey, not sure if u r writing this for the learning effect or if u just didnt know that there are libraries for such out there.
so i wanted to inform ya about $spectre console just in case u didnt know about it, its an awesome textual user interface library
Spectre.Console is a .NET library that allows for easy creation of console UIs, text formatting in the console, and command-line argument parsing.
https://spectreconsole.net/
Spectre.Console - Welcome!
Spectre.Console is a .NET library that makes it easier to create beautiful console applications.
it comes with a lot of interactive stuff as well
@cap5lut I did not know about Spectre.Console, that’s awesome info thanks! It doesn’t sound like their progress bar will work for my particular use case, per the below, but I may use some of the other features they offer.
The progress display is not thread safe, and using it together with other interactive components such as prompts, status displays or other progress displays are not supported.