Become a Patreon and get source code access:
Check out my courses:
Hello everybody I’m Nick and in this video I am going to show you how you can detect use-cases where you can make async code perform faster. The usecase is relatively nieche but common enought that you might be able to use it in one way or another.
Don’t forget to comment, like and subscribe 🙂
Social Media:
Follow me on GitHub:
Follow me on Twitter:
Connect on LinkedIn:
Keep coding merch:
#csharp #dotnet #async
is the WhenAll even needed? those tasks should be already hot when assigned
The only ways I found to create a Task without starting it is to return a Func<Task> or to explicitly create a Task object. Unfortunately, I can't find a way to initialize a new Task object with an async lambda so I rely on Func<Task>
Can we use this? catch { throw allTasks.Exception!; }
I recently started using task.whenall but this video was really well done. Thanks for making it!
Can this technique using with NHibernate (fluent) or there are some concerns about it?
Excelent work! I love this videos. One question: What is the best approach to fetch all available data? Is one of them fail, don't matter give me the others two.
so now it's not async anymore, it's async parallel 😉
great video as always Nick.
You know people calling themselves developers are getting dangerously dumb when you have to play Cpt. Obvious with a straight face (sad native code noises)
You're a hero. I just started using c# to make a web app using blazor, and have been using the html5 canvas which has all of its functions asynchronous.
I was thinking having await on every single function call is gonna mean it's basically just running sychronously, but surely they could be run in parallel. This is literally exactly what I was looking for.
Interesting, but how do you do the TaskExt.WhenAll when the params are all different types? Also, what if you need to return an ObservableCollection instead of an IEnumerable?
Thanks for your videos man we always learn a lot from you. I've tested WhenAll on a large list, it does not execute them together or faster at all though. It just lets you know when all the tasks have been complete.
The only method that made the task run in parallel is the good old Parallel.ForEach method.
Would it be possible to get your visual studio settings? Layout, color scheme, etc..
Now this is some fancy stuff, thanks Nick!
Why not handle exceptions inside the tasks?
I didn't actually realize you could get the AggregateException out of the WhenAll task, I always used to do tasks.Select(t => t.Exception). Makes so much more sense in hindsight
Great content. I had to double check my playback speed wasnt 1.25 🙂 I watched in 0.75
@3:17 you mention those tasks won't start at that point. I thought they would start but all almost at the same time? The task object returned would just represent the work being done. await doesn't start them but just doesn't let execution continue past that line until the task being awaited is done.
first like, then watch… 👍
One thing to note is that the child methods do, in fact, run immediately and only return to the main method once something is actually awaited in the child method.
Try playing around with something like this:
async Task main()
{
var t1 = Child();
var t2 = Child();
var t3 = Child();
await Task.WhenAll(t1,t2,t3);
}
async Task Child ()
{
Thread.Sleep(1000);
await Task.Delay(1000);
}
This will take 4 seconds to complete… I have seen this many times when people try to use async to achieve parallel code. If you truly want the execution to be parallel then you cannot use this method, you must do something similar to:
var t1 = Task.Run(Child);
var t2 = Task.Run(Child);
var t3 = Task.Run(Child);
await Task.WhenAll(t1,t2,t3);
This will then return in the expected 2 seconds…
This aggregated exception is invalid. WhenAll returns immediately after first exception so allTasks.Exception will be non-deterministic.
You've got 69.100 subscribers man… soon 69.420
If the a chance your task function is computed, still use await, change it to return a ValueTask. This keeps .result out of your code base. No state machine is already completed.
Correction: those tasks will (probably) start running the moment you call them, Task.WhenAll doesn't start them. It just waits till they're all complete before that stack continues.
Async is NOT parallelism. Have you confused the two?
WhenAll – This is what I've done when a customer asked to check if we can make it work faster (the request was processing 10 seconds). Reduced to 8 secs. Yes, it was not so helpful, so later we had just added dynamic messages on UI, to show a user that we are actually doing something important. "Checking this, loading that, calculating, etc".
Relly useful and well explain
Fyi doing this when all on multiple db calls on same connection will not be fast at all.
A nice video showing quickly an easy parallelization win with async. My Q is how to implement task cancellation with WhenAll? With a naive implementation, the WhenAll task won't throw the taskcancelledexception until it is awaited (maybe that's the right behavior, idk)
I believe you can use Task.WhenAll(someListOfTasks).Exceptions.InnerExceptions. However, there could be null exceptions, thus to be on safe side null propagation operator can be use e.g. Task.WhenAll(someListOfTasks).Exceptions?.InnerExceptions
Hi Nick,
Thanks for the great explanation. I tried to use this (Task.WhenAll) in one of my projects, the thing is I would like to read some data from DB in each async method. But what I get is an error that in .Net Core we cannot use the same DBContext instance to call in parallel asynchronously the DB. Is there any best practice for this? Should I use different instances of DBContext in each async method? or at all this topic is not relevant for DB scenarios?
Hi .. Your video is useful for me .. I'm learn about "SignalR" . can you create some video for this topic. Thank you so much…🤗🤗
What emulator are you using to debug? I usually use the "IIS Express" and then use postman.
But the one you are using looks to be so much easier.
Excellent content. Thank you.
This seem like you are just going to push the performance cost somewhere else. This particular call will be faster (you don't have to wait for a thread to free up to run each await), but whatever thread you would have had to wait on, is now going to wait on this indirection. I suspect if you ran a concurrent workload (e.g., a web app with more than one request/second) you would not see any significant performance gains.
Great video Nick. Thanks for the Help. 🙂 Nick I have one question Might Sound Silly but bothering me a lot in fact. Why .Net core doesn't support Sync context and what exactly It mean ??
Suggestion: Video about channels
I were to high school and there i learn that the good language is c, after time i learn that c not is use usually, than they recomended i learn java se, paste time i learn that java web is more popular than they will recomended i learn java web, still they recomend c#…
How can I limit the number of threads with this All async operations? like I have 1000 requests. I want to run all but make it thread-safe. like max N thread per time. Like queue FIFO
Do you know how to do this when the api calls return different data types, string and int for example. Whenall returns void when return types are different.
About .Result vs await:
Await is more fool-proof than .Result, because if you will forget to await one of tasks in Task.WhenAll(…), then it will not blow into your face.
Also, you already have a state machine (when doing that await Task.WhenAll) so I don’t think there will be big difference if you will add few more states there.
So, I think that await is still better here