C
C#5mo ago
Eple

Question regarding tasks

Please consider the code below. Won't the usersTask run twice? And since I need its return value, isn't it unnecessary to run it within a Task.WhenAll() method?
var usersTask = service.GetAllUsers();
await Task.WhenAll(usersTask, someOtherTask);
_users = await usersTask;
var usersTask = service.GetAllUsers();
await Task.WhenAll(usersTask, someOtherTask);
_users = await usersTask;
30 Replies
Angius
Angius5mo ago
Yes, this will run twice. Once in the WhenAll(), once with this individual await And yes, if you just need to get the users, then WhenAll() is completely redundant Just
_users = await service.GetAllUsers();
_users = await service.GetAllUsers();
will do
Eple
EpleOP5mo ago
Hey @ZZZZZZZZZZZZZZZZZZZZZZZZZ, thanks for your answer. I found this via google: https://stackoverflow.com/a/38306418/11436180, can I ask you for your thoughts?
Stack Overflow
What happens when awaiting on already-completed task?
When I construct an instance of a class that I have, I would like to trigger a Token renewal function (async method) and let it run in the background (I keep a reference to the returned Task). Lat...
Angius
Angius5mo ago
Yeah I'll believe it
Eple
EpleOP5mo ago
Especially the below part, as I think it contradicts somehow with your answer.
if you await a task that is already completed it returns immediately. You could await it several times on different threads and it would only return once it has the result (or is faulted).
Angius
Angius5mo ago
I don't think I ever had to call an async method that's already been awaited before, so I have no first-hand experience of how it works
HtmlCompiler
HtmlCompiler5mo ago
the only Task you have to pay attention to is ValueTask you can't await it multiple times but in general await multiple times is kinda the wrong pattern
Eple
EpleOP5mo ago
Okay, thank you for your answer. Your willingness to help is seriously appreciated!
but in general await multiple times is kinda the wrong pattern
The thought behind my original code is that the tasks will run in parallell, but the point of the await usersTask is to retrieve its results. Since it has been established that it will immediately return the result, then I think there's no problem. And thank you for your information regarding the ValueTask.
HtmlCompiler
HtmlCompiler5mo ago
you can use .Result once the task has been awaited
Eple
EpleOP5mo ago
Cool, I'll try it!
Eple
EpleOP5mo ago
I just had a discussion with ChatGPT. I asked if .Result can be used instead of await. I'll include a screenshot. Can I ask what you think?
No description
Angius
Angius5mo ago
Instead of await? Hell the fuck no
Eple
EpleOP5mo ago
Please also see this:
No description
Eple
EpleOP5mo ago
Okay, I sense a preferance towards the code posted in my original message. Can I be so entitled and ask for an explanation to this?
Angius
Angius5mo ago
.Result is blocking awaiting frees the thread to do other work while the method executes .Result blocks the thread, not freeing it up
Eple
EpleOP5mo ago
Thanks man
Angius
Angius5mo ago
When the task is already awaited, then getting the .Result from it should technically be fine, since the long-running job is already done But I'm in favour of just blanket-banning it from the codebase with an analyzer
Eple
EpleOP5mo ago
Okay thanks. It sounds like I'm gonna take a deep-dive into C#'s source code in order to research things. Glad you could help.
Angius
Angius5mo ago
$nothread
MODiX
MODiX5mo ago
There Is No Thread
This is an essential truth of async in its purest form: There is no thread.
Angius
Angius5mo ago
if you want a deep dive into async
Eple
EpleOP5mo ago
Thanks for the link! Man, someone from Microsoft Support should be able to answer these questions. Having worked in the techinical support branch myself, it would be my job to answer these kinds of questions. Tried checking the source code – too much work.
becquerel
becquerel5mo ago
imo there's one time when it makes sense to use .Result, and it's when using task.whenall private async Task<int> foobar() { return 4; }
private void dosomething(int x){}
private async Task whatever() { var first = foobar(); var second = foobar(); await Task.WhenAll(first, second);
dosomething(first.Result); dosomething(second.Result); } in this context, you know .Result is safe and Task.WhenAll returns an array, so getting the values you care about from there is a pain i find this style a lot more convenient you could use 'dosomething(await first);' or whatever but i tend to dislike that yeah i would not try to learn async by reading the implementation 🙂 there are some good blogposts that are a better introduction. cleary's blog linked above is a good knowledge source as well
becquerel
becquerel5mo ago
Stephen Toub - MSFT
.NET Blog
How Async/Await Really Works in C# - .NET Blog
Async/await was added to the C# language over a decade ago and has transformed how we write scalable code for .NET. But how does it really work? In this post, we take a deep dive into its internals.
becquerel
becquerel5mo ago
as is anything by stephen toub
Eple
EpleOP5mo ago
I think this code example is clean. It shows how the tasks first be awaited and then their .Result properties be read afterwards.
becquerel
becquerel5mo ago
yeah it's a somewhat niche situation but it's good to know it's possible
Angius
Angius5mo ago
I wish there was some way to have a WhenAll that would give the results back Like int[] nums = Task.WhenAll<int>(first, second) Limited to tasks of the same generic type of course
Eple
EpleOP5mo ago
@ZZZZZZZZZZZZZZZZZZZZZZZZZ, yeah, I've looked for the same thing myself – typed out WhenAll in the IDE. Looked at the hints. Checked if it is possible to return the results. If one is eager, one could apply a push request to C#'s GitHub and suggest this – though it would require some well written documentation.
Unknown User
Unknown User5mo ago
Message Not Public
Sign In & Join Server To View
SleepWellPupper
SleepWellPupper5mo ago
just do myValueTask.AsTask() and you're fine write it yourself, it's a good exercise for getting into TPL apis :)
Want results from more Discord servers?
Add your server