await in Console App breaks my switch menu
Hi! So, I'm a .Net softdev student and I am building a facility booking app as a project, using C#, EF and SQL database. The app works great. But our teacher just came up with an extra feature and wants us to implement an async method somewhere in the code. I chose to do it to read bookings from the database. Here is my code in question, starting with the async method and the admin menu calling it.
If I ommit the 'await' in the method call in case 7, evertything works fine, when the method runs and ends but of course, the call is synchronous and is not interesting for my teacher. But when I use 'await' in case 7. The method is run well, the bookings are printed to the console. But that is when mayhem starts to happen. The menuChoice is broken when the method exits and the app is behaving very strangely, jumping between menus. I guess it has to do with how threads work with async-await but can't find any solution or help. I have been to deep on Stack I think I met Ada Lovelace, but she couldn't help. So I turn to higher powers. Anyone on this one? I have debugged for exceptions but everything is fine in that matter. The ViewBookingsAsync Task and the AdminMenuAsync Task are the only async methods in my whole code, might be worth mentioning.
25 Replies
Still reading through, but omitting 'await' doesn't make it synchronous
Show where you call AdminMenuAsync please
That's why
You're not awaiting it
so, should AdminLogin be made async and await the method call?
Yes
async Task
in its turn, AdminLogin is called from another method, called in Main. Should all these be made async and await?
Yes
including Main?
Yes
This is why 'async' is called 'viral'.
As soon as you introduce it, it spreads all the way to the top
Alright, so starting from Main, which also should be an async task, All methods leading to ViewBookingsAsync have to be async tasks and await the next async method call
Correct
async Task Main => await StarmenuAsync() => await AdminMenuAsync() => await ViewBookingsAsync(). Anything else can remain regular void or else methods
This is a beautiful mess!
😁
I guess this is not a problem while working with Webapps with a GUI but not ideal for console
Will try it ASAP! Thanks so much for oyur help!
It's pretty similar tbh,
Ok, this works until I enter case 9 and "log out" to go back to StartMenu. If i log in again, the same problem happens after exiting case 7
static async Task Main(string[] args)
{
Helpers.AddData.AddAllTestData();//Calls all methods adding bulk data if the database is not yet populated
await Helpers.Menu.StartMenu();
}
This is my Main
I don't know what the original problem is- could you clarify?
Also show the logout code
$code
To post C# code type the following:
```cs
// code here
```
Get an example by typing
$codegif
in chat
For longer snippets, use: https://paste.mod.gg/
Guess the Logout should be async task too and await StartMenu()?
The problem that happens is that when exiting an async process, The user input gets completely scrambled in AdminMenuAsync(). And the switch cases do not work as expected, throwing you back to StartMenu() for example
That looks like you're not properly managing a main loop, you're just recursing deeper
And yeah, you're doing the same mistake as earlier and not awaiting an async method
I guess I do not event need a LogOut method then, and just exit the switch when the right user input is entered
If"start menu" is your root call in Main, you should not be re-calling from anywhere else
Yeah, now I get it
This works!! I removed the log out method and broke out of the case by setting the loop to false. This way I could go back to the previous menu without any problems.
Thanks a lot for the help
Much appreciated
Tbh it is more problematic in apps that have a main thread. There you have to make sure to return back to the calling thread in the right places
Elsewhere you can leverage
.ConfigureAwait(false)
to tell the task to not bother returning back to the calling thread
Now that got a bit technical for my level. Might be a stupid question, but would you be able to run and call these methods async anyway without going back to the main thread