DEV Community

Cover image for How YOU can make your .NET programs more responsive with async/await in .NET Core, C# and VS Code

How YOU can make your .NET programs more responsive with async/await in .NET Core, C# and VS Code

Chris Noring on November 12, 2019

Follow me on Twitter, happy to take your suggestions on topics or improvements /Chris When we run synchronous code we block the main Thread from ...
Collapse
 
tyrrrz profile image
Oleksii Holub • Edited

await Task.FromResult that's a good one 😂
You're confusing Task.Run with Task.Result. The latter doesn't do any calculations, it just returns a completed task that you don't need to await. In fact, awaiting it just creates an unnecessary state machine that can hurt throughput.

Collapse
 
softchris profile image
Chris Noring

Well the Task result is immediately known, i.e 1+2, which is what I 'm using it for docs.microsoft.com/en-us/dotnet/ap.... Is it the best use of it? Probably not. Could I have been using Task.Run? Probably. The whole point of that method is generally to showcase the async/await combination. I think you are reading too much into a first sample method Alexey. I was making an analogy to Promise.resolve in the JavaScript world...

Collapse
 
tyrrrz profile image
Oleksii Holub

The point here was that using await with Task.FromResult is unnecessary and counterproductive.

Thread Thread
 
softchris profile image
Chris Noring

That I agree with.. I was showcasing async/await .. I will update the text to talk about the difference of Task.Run and Task.FromResult

Collapse
 
slavius profile image
Slavius

TPL and async/await have nothing in common. I can write code like:

// Calculate prime numbers using a simple (unoptimized) algorithm.

IEnumerable<int> numbers = Enumerable.Range (3, 100000-3);

var parallelQuery = 
  from n in numbers.AsParallel()
  where Enumerable.Range (2, (int) Math.Sqrt (n)).All (i => n % i > 0)
  select n;

int[] primes = parallelQuery.ToArray();
);

and converting it to async/await will not make it any faster if not the opposite.

Async/await has its specialized use cases when calling a method actually needs to spawn another thread (be it a networking or filesystem thread) that pre-empting your own thread within the operating system actually allows for other threads to run.
Please do not make async/await a golden hammer when it is clearly not.

Collapse
 
softchris profile image
Chris Noring

I appreciate your feedback. Yes, the article is about making programs be more responsive in those specific use cases, i.e File system operations, Web Request.. My examples should have been about that. I also wanted to show how Tasks and async/await worked together, which is why I opted for simpler tasks that didn't do those things. But you are right, it's not a golden hammer, but used correctly can greatly improve your program

Collapse
 
slavius profile image
Slavius

I didn't want to be rude but IMHO each article should start with a preface where there is mentioned for what it is discussed technology/framework best suited and where it is not.
I appreciate you bringing this topic into focus as it is important. It is rare to see a server with single core nowdays, and parallel programming should be understood by most programmers.

Collapse
 
bellonedavide profile image
Davide Bellone

Cool! Thanks for sharing :)
Just a tip for who is approaching async programming for the first time: in general it's not a good idea to use .Result since it wraps exceptions into an inner field.
code4it.dev/blog/asynchronous-prog...

Honestly, I haven't tried what happens if an exception occurs while using Task.WaitAny() :)

Collapse
 
siamcr7 profile image
Jamil Siam

Just to clarify, "Task.WaitAll(...)" is essentially same as "await Task.WhenAll(...)". Please correct me if I am missing something.

If I am correct in my above statement, then shouldn't latter be the best approach to wait for all the tasks to complete?

Collapse
 
softchris profile image
Chris Noring

WaitAll and WhenAll is very different. WaitAll blocks the code on that line. WhenAll returns directly with a Task.. As for await Task.WhenAll(), yes you can do that... As for one approach is better than another, not sure tbh.. I do know that when I get a task back I have the capability check it's state, cancel it and so on.. With that said, I suppose WhenAll gives us more fine-grained control to affect all three Tasks like cancel all, cancel one etc... With WaitAll I'm stuck at that line so it might be tricky to do anything but just wait. So if we ar talking about more fine-grained control I lean on agreeing with you.

Collapse
 
carlillo profile image
Carlos Caballero

Thanks Chris for this post!

Collapse
 
softchris profile image
Chris Noring

Thanks Carlos :)

Collapse
 
deanagan profile image
Dean

Hi Chris, awesome article! I have a question. When either WhenAny or WhenAll returns with a task, are the tasks already executing at that point and could finish before interacting with it?

Collapse
 
softchris profile image
Chris Noring

I would say yes. They are already running.. You can check that on task.Status for a specific Task or var taskWhenAll = Task.WhenAll(t1,t2,t3) and taskWhenAll.Status

Collapse
 
amul047 profile image
amul047 • Edited

Are you meant to say WaitAll to WaitAny in this section? thepracticaldev.s3.amazonaws.com/i...

Collapse
 
softchris profile image
Chris Noring

hi... No I mean WhenAll. So WhenAll returns right away, it returns a Task, which means it carries out the next line of code which is to calculate time taken. WaitAll blocks and this why we get a higher time taken.. (We wait until the slowest task in WaitAll have finished until we continue with the next line of code)

Collapse
 
amul047 profile image
amul047

Awesome, thanks for the clarification

Collapse
 
immersivegamer profile image
Henry Nitz

Any thoughts on continuations with tasks? I haven't yet had a need to use them, but it seems like a easy way to ensure behaviour executes after a task is completed.

Collapse
 
softchris profile image
Chris Noring

they are good.. definitely use them. I am linking to them in the references section. I just thought the article was long enough.. :)