Await Async Tasks Are Getting Awesome in .NET 9!

  Рет қаралды 105,464

Nick Chapsas

Nick Chapsas

Күн бұрын

Until the 21st of April, buy ANY Dometrain course and get the From Zero to Hero - LINQ in .NET course for free!! dometrain.com/...
Become a Patreon and get special perks: / nickchapsas
Hello, everybody, I'm Nick, and in this video I will introduce you to a brand new await async and Task feature coming in .NET 9!
Workshops: bit.ly/nickwor...
Don't forget to comment, like and subscribe :)
Social Media:
Follow me on GitHub: github.com/Elf...
Follow me on Twitter: / nickchapsas
Connect on LinkedIn: / nick-chapsas
Keep coding merch: keepcoding.shop
#csharp #dotnet

Пікірлер: 219
@tehsimo
@tehsimo 10 ай бұрын
Lovely feature BTW that zoomed middle region messes with my brain
@Ilix42
@Ilix42 10 ай бұрын
Great video as always. One bit of feedback, please provide a link to referenced blog posts, especially when they're so old. Thanks!
@yuGesreveR
@yuGesreveR 10 ай бұрын
OMG!!! I've been waiting for this feature for years!
@sinan720
@sinan720 10 ай бұрын
You could've just used System.Linq.Async. This functionality has already existed for years
@marvinjno-baptiste726
@marvinjno-baptiste726 10 ай бұрын
Been waiting for this for so long. Totally perplexed as to why it has taken so long for something so fundamental.
@dawizze1
@dawizze1 10 ай бұрын
I hope to see some F# content on Dometrain one day. Love to learn how to leverage the language to write apis.
@aborum75
@aborum75 10 ай бұрын
It's great to see an continuous investment in all areas of the framework. Would like to see more focus on reactive extensions (RX) though, especially around async APIs.
@obinnaokafor6252
@obinnaokafor6252 10 ай бұрын
There is a going effort to improve RX
@martinmanchev1276
@martinmanchev1276 9 ай бұрын
The new feature looks good. There is an old way to achieve the same: var tasks = Enumerable.Range(1, 5).Select(Calculate).Select(async i => Console.WriteLine(await i)); await Task.WhenAll(tasks); Here you reuse the defer idea of the LINQ
@pawerobak6655
@pawerobak6655 6 ай бұрын
I have used similar but with exception handling: var tasks = Enumerable.Range(1, 5).Select(Calculate).Select(i=>i.ContinueWith(i=>Console.WriteLine(i)));
@cemsayn9588
@cemsayn9588 10 ай бұрын
Thank you Nick for sharing this great feature. I have implemented my own as many of us for a batch System IO operation. I was checking in a While loop with task has completed, cancelled or hasException properties. Then removing from batch operation array and adding new one to task array. I don't know why Microsoft wait for this feature so far.
@orterves
@orterves 10 ай бұрын
What happens when an exception is thrown by one (or more) of the tasks?
@vinydanylo
@vinydanylo 10 ай бұрын
I think an AggregateException would be thrown.
@daravango
@daravango 10 ай бұрын
My guess is an exception will be thrown when you `await` an individual task, and regarding the entire `await foreach` block, my guess would be: same behavior as `await`ing a `Task.WhenAll()`
@victor1882
@victor1882 10 ай бұрын
I would expect that you get the exception when awaiting, or check and don't await if the task is faulted
@Crozz22
@Crozz22 10 ай бұрын
Exception won't be thrown until you await the task. So it would not be thrown by Task.WhenEach.
@vothaison
@vothaison 10 ай бұрын
Well, that's what people will explore for themselves.
@C0X0S
@C0X0S Ай бұрын
Always solid and easy explaination, thx
@ricardoduarte442
@ricardoduarte442 10 ай бұрын
I would love to see a video of you looking at the implementation by microsoft and explaining why it is better :) Great vid as always Nick
@jonasgranlund4427
@jonasgranlund4427 2 ай бұрын
I have a couple of places where I use Task.WhenAny together with large lists of tasks, so I iterate over a worklist of 100 task in parallel out the full list of 500-10000 total tasks and as soon as one of the 100 is ready I add a new one of the full list into my work-list and process til the full list is empty. I think that have worked quite well and a lot better than to try to do Task.WhenAll on 5000 tasks, even though it is a lot better now than on C# 5 when it went into Thread starvation Overload :) :)
@rmcgraw7943
@rmcgraw7943 8 ай бұрын
await foreach does this by default IAsyncEnum. U don’t need wheneach. the issue is locking, hence you need to customize your partitioner
@joepurdom2528
@joepurdom2528 10 ай бұрын
Couple questions 1. When using WhenEach what thread does the Consle.WriteLine execute on? 2. Is any overhead introduced by using await task vs task.Result, given the fact that we know task.Status == RanToCompletion? Or maybe we don't know that, depends on how errors are handled. 3. Any difference in performance using WhenEach over await Task.WhenAll(tasks.Select(t => t.ContinueWith(async x => Console.WriteLine(await x)))); or is it just cleaner to look at?
@mohamedeffat54
@mohamedeffat54 10 ай бұрын
seconding question 3, I'd assume since nick didn't mention it that ContinueWith in general won't give the same intended behavior but I want to actually know.
@tareksalha
@tareksalha 10 ай бұрын
We are performing many of those independent tasks. Up until now, we have been using queues to solve the problem.
@devwatch2359
@devwatch2359 9 ай бұрын
Best segue into a course advertisement ever! So smart, so smooth... I applaud you.
@oleksii766
@oleksii766 10 ай бұрын
As an option we can use a some kind of the Pub/Sub approach to subscribe to the results as they appear
@AlFasGD
@AlFasGD 10 ай бұрын
The video is very weirdly zoomed in some areas
@urzaaaaa
@urzaaaaa 10 ай бұрын
It's because the author is naked. He says it briefly right at the beginning of the video.
@AlFasGD
@AlFasGD 10 ай бұрын
@@urzaaaaa what the fuck are you saying
@felipe.raposo
@felipe.raposo 10 ай бұрын
​@@urzaaaaa😂😂😂
@sammtanX
@sammtanX 10 ай бұрын
​@@urzaaaaathat's crazy
@LC12345
@LC12345 10 ай бұрын
@@urzaaaaaYes, he certainly does!
@timdoke
@timdoke 10 ай бұрын
I've been using the exact approach you showed with WhenAny for quite a while. It's good there's an easier way, and more performant way to do it though.
@stunna4498
@stunna4498 9 ай бұрын
“Hello everybody my name is marioooo” sorry this was in my head when i heard the intro 😭😭😭😂
@danbopes
@danbopes 10 ай бұрын
This is a nice addition to the task echo system for sure!
@rmcgraw7943
@rmcgraw7943 8 ай бұрын
I love LINQ, but be aware that it is implemented via extension methods, aka. anonymous methods, aka delegates, so they are allocationed on the heap, where inline fuctions go on the stack.
@andrewallshouse4525
@andrewallshouse4525 10 ай бұрын
Hey Nick love this!! Can you post the link to the Stephen Toub article?
@nickchapsas
@nickchapsas 10 ай бұрын
devblogs.microsoft.com/pfxteam/processing-tasks-as-they-complete/
@wojciechwilimowski985
@wojciechwilimowski985 9 ай бұрын
If you want to process tasks as they happen, you're two steps away from the point when it's serious enough to use System.Threading.Tasks.Dataflow
@supreme_dev
@supreme_dev 10 ай бұрын
Late happy birthday Nick! keep up with the great work
@rogeriobarretto
@rogeriobarretto 8 ай бұрын
Do you have to await also the element of the task in the foreach loop? Will it trigger the task again, I assumed you would get the result straight back
@michaelsniknejs6326
@michaelsniknejs6326 10 ай бұрын
@3:43 "ton" although spelled with an "o" is actually pronounced "tun" (rhymes with "fun").
@kaiserbergin
@kaiserbergin 10 ай бұрын
I'm trying to think of where I would use this... In examples like this, I would usually write a method or a class that orchestrates the order of events. The signature would return a task that encapsulates the order of events. I don't doubt this has valid use cases, I'm just curious to see how people plan on using it and if there's something I'm missing.
@lukeno4143
@lukeno4143 5 ай бұрын
why do you Console.WriteLine(await task); if the task was already completed before it gets to this statement? youre not (a)waiting for anything at this point. So whys it called await here? should it just be Console.WriteLine(task.Result)? and are the two identical at least since Result is already finished?
@realtimberstalker
@realtimberstalker 10 ай бұрын
I feel like a simple solution to do this before .net 9 would have been to just wrap the task with another task that handles the result, and then awaitall those tasks instead.
@simonwood2448
@simonwood2448 10 ай бұрын
Indeed. I fail to see the excitement here, it's a trivial thing to solve
@realtimberstalker
@realtimberstalker 10 ай бұрын
@@simonwood2448 This is syntactic sugar that is easier to use and reduces boilerplate. It’s certainly better. Im just saying I feel the original problem itself wasn’t some impossibly hard thing.
@protox4
@protox4 10 ай бұрын
That's not the same, though. That will process the results concurrently, while the new method processes sequentially.
@TazG2000
@TazG2000 10 ай бұрын
@@protox4 In the new method the tasks are still running concurrently, but the loop is responding to when each one completes. So this should, in theory, work the same way: await Task.WhenAll( tasks.Select(async t => { Console.WriteLine(await t); }));
@TazG2000
@TazG2000 9 ай бұрын
@@xybersurfer A couple points: 1. In practice, that probably wouldn't be true. If we're developing a UI where we need to avoid sending UI outputs concurrently, that would aready be taken care of by the synchronization context. The outputs would be queued to run on the same thread where we are using the await statement (the UI thread). 2. If we actually need to make sure these outputs _specifically_ aren't concurrent, all we need is a lock statement. We don't need to do any manual "ugly" implementations to make this work. To be clear, it's really nice that we can do this with "await foreach" now, but the point is most of these problems that used to be very complicated to solve are already quite simple now, so this new addition isn't really a game changer, it's just nice to have.
@thomassarmis
@thomassarmis 9 ай бұрын
Why not appending a .ContinueWith() and then do the WhenAll() ? would the end result be the same?
@RuiSantos78
@RuiSantos78 4 ай бұрын
Yeah, I normally do that way ...
@Pierre1O
@Pierre1O 29 күн бұрын
you won't be able to catch exceptions in try/catch block, you'd need then to check each continued task if faulted or not.
@noellysaght1007
@noellysaght1007 10 ай бұрын
I achieved similar functionality using ActionBlocks from the TPL. I can see the benefits of this approach and how concise it is, but I think the functionality available in the TPL is under utilised when it comes to async processing.
@naftalyweinberger7892
@naftalyweinberger7892 10 ай бұрын
nick i am a huge fan of the dometrain courses, but I would prefer, that the presenters should make prepared slides rather then drawing while talking, it slows things down and i prefer when they talk FAST. deep dive C# is GGOOOOODDDDD
@amantinband
@amantinband 10 ай бұрын
Thank god we have Stephen. Btw I think the following PLINQ does the same: await ParralelEnumerable.Range(1, 5) .ForAll(I => Comsole.WriteLine(Calculate(I)))
@nickchapsas
@nickchapsas 10 ай бұрын
I think the difference is that WhenEach will give you back the Task itself, not just the result so you have more flexibility on how you handle failure
@user-dc9zo7ek5j
@user-dc9zo7ek5j 9 ай бұрын
@@nickchapsas I can't think of a use case where you want to continue the method without awaiting all tasks... additionally are 2 ways to do the thing you're describing already. 1. Creating a method that consumes the original method's value and add there the custom logic. 2. Use continuations. Here is a small program to demonstrate the second case: foreach (var t in Enumerable.Range(1, 6) .Select(async n => { await Task.Delay(new Random().Next(0, 10)); return n; }) .Select(t => t.ContinueWith(v => Console.WriteLine(v.Result)) .ToArray()) await t;
@petrx-ray9766
@petrx-ray9766 9 ай бұрын
@@user-dc9zo7ek5j Absolutely agree! I've never heard about the problem which Nick described, as it is easily handled by continuations.
@JohnWilliams-gy5yc
@JohnWilliams-gy5yc 9 ай бұрын
Not exactly the same under the hood. I guess "parallel" is named because it "must" be paralleled. With it, you want to request some OS threads to work on your tasks, not "limited" in only the running thread concurrency realm.
@timjackmaster1385
@timjackmaster1385 10 ай бұрын
Very very nice feature. Has anyone benchmarked how much more efficient it is in comparison to the old approach?
@JackBauerDev
@JackBauerDev 10 ай бұрын
Wow that was way nicer than I expected
@rmcgraw7943
@rmcgraw7943 8 ай бұрын
IAsyncEnemerable where the source is yielded via a PLINQ. For or Parallel.for with custom partitioner
@haxi52
@haxi52 10 ай бұрын
Generally if I have a set of tasks I need chained, I'll wrap the call chain into another async method. So the caller really just needs to wait till everything is done.
@7th_CAV_Trooper
@7th_CAV_Trooper 10 ай бұрын
Why would you use a list instead of array in this sample?
@j1shin
@j1shin 10 ай бұрын
Because of Remove()
@zpa89
@zpa89 10 ай бұрын
To expand on the other reply, it only works because it removes items from the list and you cannot remove items from an array. You would have to splice/copy the items to a new array. List works similarly behind the scenes but Microsoft is much better at optimization than you or I.
@gronkymug2590
@gronkymug2590 10 ай бұрын
I assume "await task" throws just for the specific task on exception, so we can nicely process errors of each task. I like it.
@tomtoups
@tomtoups 10 ай бұрын
That's great if the T in Task[] are all the same. but if I'm calling multiple APIs using implicit parallelism, for example, and they all return a different types, then it doesn't really help me
@warrenbuckley3267
@warrenbuckley3267 10 ай бұрын
You could work around that by using Task. Then you could pattern match to figure out what model was returned.
@tomtoups
@tomtoups 10 ай бұрын
@@warrenbuckley3267 Yeah that's an idea. 👍
@Cafe-O-Milk
@Cafe-O-Milk 10 ай бұрын
@@warrenbuckley3267 very costly
@tahaali01
@tahaali01 10 ай бұрын
So simple and clean, great!
@michaelakin766
@michaelakin766 9 ай бұрын
why do you have to do the await on the foreach and then on the task? It seems like the task is being called two times.
@timur-mut
@timur-mut 10 ай бұрын
Great feature, thanks for explanation.
@handlez411
@handlez411 9 ай бұрын
Very very cool! 🥳
@diegoronkkomaki6858
@diegoronkkomaki6858 10 ай бұрын
Not completely happy about the need to await the task inside the Task.WhenEach loop. If the WhenEach is supposed to yield a completed task why not access the result immediately in the loop, why the need to await the task "again"? EDIT: Is it because the tasks can return different types of results?
@scottbaldwin2477
@scottbaldwin2477 10 ай бұрын
You need it for error handling. This pattern lets you await a task in a try/catch, deal with any exceptions, and then continue iterating.
@jongeduard
@jongeduard 10 ай бұрын
@scottbaldwin2477 Exactly, the place where the await is, there will happen the possible throws. Writing the entire thing myself while watching this video made that clear for me already. You can put a try block inside your await foreach block to handle each individual failed task. Which is the problem that you cannot with Task.WaitAll for example, which completely stops everything on the first exception.
@diegoronkkomaki6858
@diegoronkkomaki6858 10 ай бұрын
@@scottbaldwin2477 ah, of course. Makes sense.
@diegoronkkomaki6858
@diegoronkkomaki6858 10 ай бұрын
​@@scottbaldwin2477 Right, makes sense.
@Cool-Game-Dev
@Cool-Game-Dev 10 ай бұрын
That is beautiful, thank you!
@lordmetzgermeister
@lordmetzgermeister 10 ай бұрын
I figured it would be solved by IAsyncEnumerable as that makes the most sense. Finally :)
@bgrant1512
@bgrant1512 10 ай бұрын
Wake me up when they make EF Core async friendly. That would make a huge difference.
@JeppeRaskDK
@JeppeRaskDK 9 ай бұрын
Looks cool, but couldn't you just move the "Calculate()" call to an async method which awaits and does the post-processing and then finally Task.WhenAll on those? I rarely have a List of tasks that I don't control the creation of.
@MaximT
@MaximT 8 ай бұрын
For now you can use TPL Dataflow
@jell0goeswiggle
@jell0goeswiggle 9 ай бұрын
Ive written that while loop before. Feels bad / looks ugly, but what are you going to do. I'm still enjoying great new things in .NET8, I dont need to be excited for 9 yet!
@xd-hood-classic
@xd-hood-classic 9 ай бұрын
Last time I had this problem, I just went with firing an event after task is done
@cdoubleplusgood
@cdoubleplusgood 10 ай бұрын
"A sink a wait". I've seen it.
@bluecup25
@bluecup25 10 ай бұрын
I just realized we're as far from 2012 as 2012 was from 2000
@CezaryWalenciuk
@CezaryWalenciuk 10 ай бұрын
Ok what version of .NET 9 preview is this working. There is no "WhenEach" method
@Crezber
@Crezber 9 ай бұрын
good question
@derangedftw
@derangedftw 10 ай бұрын
Wow, finally!
@mome3807
@mome3807 10 ай бұрын
Does WhenEach run in parallel? hard to tell the difference to the serial syntax foreach task in listOfTasks { await task }
@sinan720
@sinan720 10 ай бұрын
Why did'nt you mention System.Linq.Async?
@kwibuske
@kwibuske 10 ай бұрын
Is there a possibility to limit number of concurrent tasks it can await at once? Because if the input list is 1000 tasks long, spinning them all together will just create a bunch of overhead.
@Biker322
@Biker322 10 ай бұрын
Probably use a SemaphoreSlin
@RealCheesyBread
@RealCheesyBread 10 ай бұрын
Wait so what's the difference between `Task.WhenEach()` and `tasks.ToAsyncEnumerable()`?
@nanvlad
@nanvlad 10 ай бұрын
WhenEach() is in BCL whereas ToAsyncEnumerable() is an reactive extension from System.Linq.Async
@RealCheesyBread
@RealCheesyBread 10 ай бұрын
@@nanvlad But other than that, no difference?
@nanvlad
@nanvlad 10 ай бұрын
@@RealCheesyBread BCL should be more reliable and performant. Also it can be improved by Microsoft on the very low level.
@ThugLifeModafocah
@ThugLifeModafocah 10 ай бұрын
that's really good indeed.
@mirrorless_mirror
@mirrorless_mirror 9 ай бұрын
Nice feature. But I will actually have to wait for a next LTS version of .NET (likely 10) to use it in the real life.
@LordErnie
@LordErnie 10 ай бұрын
Why not just use channels with separate sessions if you need resource syncing over single groups of tasks in a short process?
@pagorbunov
@pagorbunov 10 ай бұрын
Because it would be overkill
@jorgepedraza1275
@jorgepedraza1275 9 ай бұрын
🤔 interesting!
@krccmsitp2884
@krccmsitp2884 10 ай бұрын
That looks neat!
@digibrett
@digibrett 10 ай бұрын
This is awesome!
@sunefred
@sunefred 10 ай бұрын
Very very elegant.
@jesusdelarua5995
@jesusdelarua5995 10 ай бұрын
I do not see WhenEach() available in my .NET 9 Preview version. Getting Compiler Error CS0117 Task' does not contain a definition for 'WhenEach' My version is 9.0.100-preview.2.24157.14 Ideas?
@xMadClawx
@xMadClawx 10 ай бұрын
Same, I don’t even see it in the dotnet 9 preview on GitHub
@johncerpa3782
@johncerpa3782 10 ай бұрын
Great video
@As_Ss
@As_Ss 10 ай бұрын
Its taken so long as this was non issue, can be done in multiple ways. Normally u would limit the Tasks logical threads for example with max degree of parallel cuz u dont want to run more than that, so a new task wont start until there is place for another anyway and when that happens the ended task can report. This function is just a cherry on the ice cake.
@d3tn3tracer
@d3tn3tracer 9 ай бұрын
Finally! :)
@LogicException
@LogicException 10 ай бұрын
Wild effect in this video
@squaredcircle8833
@squaredcircle8833 4 ай бұрын
What about Parallel.ForEachAsync?
@F1nalspace
@F1nalspace 10 ай бұрын
I don't see any use-case for that feature. Just use a queue und do a while with await for each loop... you can even do a concurrent queue and do a parallel foreach... but still, what is the use-case for this? Process N-Items with the same type, waiting for each type until it its finished... thats like normal basic programming, not using any tasks at all... the point of tasks is do stuff in parallel - using the actual cores of a CPU, which people tend to forget that there is actual hardware running that code. Even in cases, where i do heavy data transformations and require multiple steps, even then i would not do it this way... maybe scrapping a website, parsing links... to prevent API blocking, due to too many request, would be the only use-case i could think of... Even multiple IO-access can still be done in parallel...
@andriiyustyk9378
@andriiyustyk9378 10 ай бұрын
5:40 Why "tasks.Any()" instead of "tasks.Count > 0"?
@zpa89
@zpa89 10 ай бұрын
Any seems a semantically easier to read. It is English not math. Plus no hard coded number. Technically slower, but modern computers can do billions to trillions of flops and the vast majority of all use cases will be bottlenecked by unmanaged resources like IO and network.
@keyser456
@keyser456 10 ай бұрын
@@zpa89 Are we after performance or more readable code? Gotta pick one.
@zpa89
@zpa89 10 ай бұрын
​@@keyser456 you are neglecting that modern dotnet puts some SERIOUS effort into optimizing linq expressions. In fact, I would bet the compiler optimizes away the more basic extensions entirely when the underlying runtime type is known.
@keyser456
@keyser456 10 ай бұрын
@@zpa89 I'm neglecting nothing. There's an unhealthy obsession for "clean code", and it's to the point where people (by your own admission) are willing to trade off some performance. Will a tiny perf tradeoff be the deathblow in an app? Probably not. Is .Any() really that much better than Count > 0 from a readability standpoint? Definitely not. We're programming, not writing a book for kids.
@zpa89
@zpa89 10 ай бұрын
@@keyser456 we are all humans. We are writing code that humans must maintain. As humans, we speak in human languages. Writing code in a more naturally human way makes code easier to read. When a human wants to decide whether they have to deal with something, they ask "are there any x left?" They don't say "is the count of x greater than zero?" Beyond that, the vast majority of software engineers are dealing with IO/network bound work. CPU cycles you save by hyper optimizing your code pale in comparison to the time you must spend waiting for unmanaged requests to return. I would love to say that one day you will learn all of this but I have interviewed hundreds of engineers from all over the world, I lead a team of 60+, and unfortunately it seems that tenure just does not make you a more intelligent engineer. If you aren't one of the bright ones now, you may never be.
@MrOboema
@MrOboema 3 ай бұрын
Fun fact: the existing solution in the Nito.AsyncEx package is lot more readable than the .NET 9 version 🤣
@montanomariano
@montanomariano 10 ай бұрын
Awesome!
@RoBBed13
@RoBBed13 9 ай бұрын
This is nice
@oct8bit
@oct8bit 10 ай бұрын
This nice one
@weicco
@weicco 9 ай бұрын
If people just used async methods and, what is even more important, would use CancellationToken so that api calls could actually be cancelled!
@JustaFrogger
@JustaFrogger 10 ай бұрын
Great!🎉❤
@MEZOMEZO2011
@MEZOMEZO2011 9 ай бұрын
What is an actual use for this?
@MrBurikella
@MrBurikella 10 ай бұрын
Well, I think the easiest way would be to get a list of tasks which includes processing. Like `Enumerable.Range(1, 5).Select(async order => Console.WriteLine(await Calculate(order)))`. Clearly you can replace `Console.WriteLine` by anything else. I think it is much cleaner and easy to grasp.
@protox4
@protox4 10 ай бұрын
It's not quite the same, though. That will process concurrently, while the new method processes sequentially.
@MrBurikella
@MrBurikella 10 ай бұрын
@@protox4 right, that requirement wasn't stated explicitly
@zpa89
@zpa89 10 ай бұрын
​@@MrBurikellathat is literally the entire point of the video....
@VandroiyIII
@VandroiyIII 10 ай бұрын
Looks useful. Though I'm a bit torn about the ever increasing number of syntactic special cases in C#. The for, foreach, and now await foreach loops often take the place of higher-order functions, but proper higher-order functions are a bit crippled in their own special way. Doesn't this feel a bit like these projects where people only ever add features, but never refactor? A new programmer these days seems to be learning more and more cryptic rules for each real concept behind them.
@chris-pee
@chris-pee 10 ай бұрын
To be fair, "await foreach" (IAsyncEnumerable) was added in 2019 in C# 8.
@Cool-Game-Dev
@Cool-Game-Dev 10 ай бұрын
C# has always supported backwards compatibility when possible.
@Grimlock1979
@Grimlock1979 10 ай бұрын
Yeah, this feature was long overdue.
@the-avid-engineer
@the-avid-engineer 10 ай бұрын
It seems odd that it returns an async enumerable of tasks, and not the results. I’m sure there’s a good reason for that but.. yeah.. odd.
@ErazerPT
@ErazerPT 10 ай бұрын
Maybe I'm just an old gezzer, but... if you want something done as they finish, why not pass them a callback? Yes, i know, context is gone, but if that is so paramount, is it not more of a "code smell" than anything else?
@milkandhenny
@milkandhenny 10 ай бұрын
Callback hell, from nesting too many call backs is inevitable the moment a project becomes even the slight bit complex I'd assume. Being able to write I/O and other async tasks in a synchronous way just makes larger code bases more understandable for larger teams, or even yourself in the future
@petrusion2827
@petrusion2827 10 ай бұрын
You could've already done that by calling Task.ContinueWith(...) on all of the tasks in the list, if you want to deal with it and the problems that arise. C# was one of the first languages to use async await so it makes sense that the standard library is going to use it where it can. After all, "Callbacks are the goto statement of our generation"
@ErazerPT
@ErazerPT 10 ай бұрын
@@milkandhenny How does nesting come into play? Something like OrderComplete(int order){...} being passed to something like Task ProcessOrder(int order,Action callback) was all they needed to finish their work, no nesting here, it's fully local. By the time WhenAll() resolves, you know they all went through OrderComplete() and move on. Think you're conflating "work completion callback" with "forward return point callback". The first finishes work, but the calling site is still waiting. The second IS the "forward return" point because the calling site IS NOT waiting.
@adambickford8720
@adambickford8720 10 ай бұрын
@@ErazerPT As long as none of your calls have dependencies, callbacks aren't terrible. As soon as you start having to coordinate them, callbacks are terrible.
@ErazerPT
@ErazerPT 10 ай бұрын
@@adambickford8720 Once more, those are NOT the kind we are talking about. And yes, you're 100% right but Task's don't magically free you from it. If you're accessing shared resources, you'll still need some sort of await semaphore. Concurrency IS hell.
@xelesarc1680
@xelesarc1680 10 ай бұрын
Hi nick i need you help😢, i had some problem with parallel and async , i had 1000 batch data but need make it faster, i use parallel but got error in database why i cant crud if i use parallel , iam using sqlserver . If you read this maybe you can help me iam stuck 😢😢
@romanhrytskiv8845
@romanhrytskiv8845 10 ай бұрын
Very nice
@ValueLevit
@ValueLevit 10 ай бұрын
Am I missing something? tasksWithContinuation = taskList.Select(t => t.ContinueWith(delegate)).ToList();
@ricardoduarte442
@ricardoduarte442 10 ай бұрын
You are passing a delegate, won't resolve in the main thread, I think that is the difference
@ValueLevit
@ValueLevit 10 ай бұрын
@@ricardoduarte442 if there's such a requirement then the needed behavior can be configured in the ContinueWith method.
@protox4
@protox4 10 ай бұрын
That will process the results concurrently, while WhenEach processes sequentially.
@ricardoduarte442
@ricardoduarte442 10 ай бұрын
@@protox4 Oh yeah true LOL
10 ай бұрын
Or you could just have a function that does the Calculate(i) AND console.writeline ... WhenAll - that still does what it is suppose to do - waits for all of them.
@felipesfaria
@felipesfaria 10 ай бұрын
This was my thought. It's what I would do in this situation.
@luvincste
@luvincste 10 ай бұрын
thought this was a video about async2
@protox4
@protox4 10 ай бұрын
He did a separate video about that. And that's just an experiment currently, not officially in 9.
@Matlauk
@Matlauk 10 ай бұрын
You said "no lists involved" when there is obviously a list involved. I understand enough that it could be any sort of IAsyncEnumerable but your code sample still used a list.
@ricardoduarte442
@ricardoduarte442 10 ай бұрын
I think is more about the allocation, is like using IEnumerable with ApplicationDbContext from EF, you are only bringing items to memory when u need them, in this case u are just getting the task pointers, not a list that have tasks (I AM NOT 100% SURE ON THIS, actually would like to see a response from Nick on this)
@gauravmanchanda4658
@gauravmanchanda4658 10 ай бұрын
It will be interesting to know what happens in race condition, if two tasks getting completed at same time, will this handle out of box or something that needs a special handling
@pagorbunov
@pagorbunov 10 ай бұрын
Since the order is not guaranteed I don't think it's an issue at all
@bogdan.p
@bogdan.p 10 ай бұрын
Something is wrong with your video as we can't see all the information. Seems like the encoding had some corrupted data.
@Suriprofz
@Suriprofz 9 ай бұрын
Still feels hacky when used to go or rust channels
@Doggettxx
@Doggettxx 9 ай бұрын
c# has channels as well, not sure why he didn't talk about it since they're much more useful in most cases
@thedarkside0007
@thedarkside0007 10 ай бұрын
this just like select in golang
@LE8271
@LE8271 10 ай бұрын
Well Nick, after buying 12 of your courses you could have given me that one for free... :/
@nickchapsas
@nickchapsas 10 ай бұрын
Email me
@Adiounys
@Adiounys 10 ай бұрын
I don't understand what was actually hard in implenting this. The examples also makes no sense. Especially the 'while' loop - what is the purpose of this? Can't you just store 'WhenAll()' in a variable and check 'if(all.isCompleted) tasks.Clear()' after 'await WaitAny(task)'? I can also think of many other, better solutions to do the same thing. It seems you picked the worst possible implementation just for the contrast... PS. Sorry for my spellings I'm writing this on my phone.
@pagorbunov
@pagorbunov 10 ай бұрын
That is why that new API was added. Instead of doing a common thing in thousand ways there would be official and most efficient one.
.NET 9 Fixed Exceptions but Still Don’t Use Them
10:01
Nick Chapsas
Рет қаралды 43 М.
Stop Using FirstOrDefault in .NET! | Code Cop #021
12:54
Nick Chapsas
Рет қаралды 102 М.
Every team from the Bracket Buster! Who ya got? 😏
0:53
FailArmy Shorts
Рет қаралды 13 МЛН
Their Boat Engine Fell Off
0:13
Newsflare
Рет қаралды 15 МЛН
«Жат бауыр» телехикаясы І 30 - бөлім | Соңғы бөлім
52:59
Qazaqstan TV / Қазақстан Ұлттық Арнасы
Рет қаралды 340 М.
That's NOT How Async And Await Works in .NET!
12:25
Codewrinkles
Рет қаралды 29 М.
The Code Smell Scam That Misled An Entire Generation Of Developers
5:22
The Logging Everyone Should Be Using in .NET
15:34
Nick Chapsas
Рет қаралды 97 М.
What's new in .NET 9 and C# 13
19:21
Filip Ekberg
Рет қаралды 22 М.
"Stop Using Async Await in .NET to Save Threads" | Code Cop #018
14:05
AI Is Making You An Illiterate Programmer
27:22
ThePrimeTime
Рет қаралды 296 М.
Fixing Your Dictionary Problem in .NET
9:19
Nick Chapsas
Рет қаралды 31 М.
Awesome new features in C# 13 for .NET 9!
10:50
Ed Andersen
Рет қаралды 15 М.
What's New for ASP.NET Core & Blazor in .NET 9
40:26
dotnet
Рет қаралды 35 М.
Every team from the Bracket Buster! Who ya got? 😏
0:53
FailArmy Shorts
Рет қаралды 13 МЛН