Live data from Hacker News

Asynchronous Programming in C#

github.com

31–40 of 186 posts

Re: Asynchronous Programming in C#

#31
post #6

We use async/await pretty much universally throughout our codebase today. One thing to keep in mind is that this mode of programming is actually not the most performant way to handle many problems. It is simply the most expedient way to manage I/O and spread trivial things across many cores in large, complex codebases. You can typically retrofit an existing code pile to be async-capable without a whole lot of sufferi…

async/await is not for CPU-intensive parallelism. I think that's pretty much stated in the .NET docs. That's why Parallel Compute APIs like Parallel.ForEeach/For are not async. Their purpose is to enable non-blocking waits for IO, as well as to do stuff like animation on UI where you might want to execute procedural code over a larger timeframe.

Re: Asynchronous Programming in C#

#33

The sync over async issue is a real common problem for me when trying to get a large older codebase converted to async and you can't just do it all at once. You still need support non async callers and you want to share code between the new async version and the old sync versions it makes it really difficult to do so. Say you have a db layer you want to move to async but you still have to support a sync api over that…

Database operations should be async, you shouldn't consume them synchronously, as they do IO. Async/Await came out in 2012, almost a decade ago (and with great first party library support, I might add).

Moralizing aside, sometimes you do want to call async APIs as synchronous code. I don't think there should be a synchronous version of the API implemented as well, you just need to do

var myValue = DoSomethingAsync().ConfigureAwait(false).Result;

which will avoid deadlocks, and execute your call synchronously

Re: Asynchronous Programming in C#

#34

Earlier quoted context omitted.

async/await is not about multithreading at all though...

In a vacuous sense, but in practice you almost always use asynchronous code to achieve concurrency. The canonical Microsoft tutorial on async spends about half its time talking about hiw to make your code concurrent to take advantage of async. https://docs.microsoft.com/en-us/dotnet/csharp/programming-g...

Concurrency does not require multi-threading. Maybe you mean parallelism? Concurrency can still be really valuable in the context of a single threaded application.

Re: Asynchronous Programming in C#

#35

I have been a C# developer for a while as well now and I'm not sure if this is true: "Use of async void in ASP.NET Core applications is ALWAYS bad. " Depending on the context, it can even be recommended to do async void. See Stephen Cleary's brilliant explanation of this: https://blog.stephencleary.com/2012/02/async-and-await.html Edit: The correct link is this, see first table column exceptions: https://docs.microso…

[deleted]

Re: Asynchronous Programming in C#

#36
post #26

>Prefer async/await over directly returning Task This one seems questionable to me. I've never been bitten by any of the cons mentioned[1], and it's even noted that doing it this way does incur performance costs. I've learned over the years that if the code path is very prolific, it pays to avoid the async state machine. I'm curious if others could expand on this one. [1] https://github.com/davidfowl/AspNetCoreDiagno…

There's a couple in here that are the absolute safest things even though the alternatives can be done safely. Async void, for example, is for dealing with event handlers.

Just like returning Task directly, if you take care with the exceptions, you'll have less problems.

Said another way "...unless you know what you're doing" could be added to a few of these.

Re: Asynchronous Programming in C#

#37

I would call myself an extremely experienced and knowledgable C# programmer with 10+ years of experience and even I found a few things surprising or new in this guide. I think C# async/await implementation is the biggest con on the .NET community, because it gets constantly hailed as one of the easiest ways of async programming but this guide itself proves to me that there are so many gotchas which are not obvious at…

Agree but it just highlights that any kind of programming with more than one linear path of execution is hard. Before async/await, coroutines, etc. we all had to learn that the hard way. It's helpful to know what a process, thread or lightweight thread in your system is and at what cost it comes. The cost and frequency of context switches is not something you can ignore and will probably be forced to profile at some point, hopefully sooner than later.

With these newer programming models there are easier ways to distribute work but unless you really dig deep and understand the basic mechanisms you will be lulled into a false sense of security.

When async was first added to .Net I read through the details of how boldly the compiler re-writes my code and I was a bit shocked, like, can it really do that? Now I always keep that in mind as soon as I start typing a...

Re: Asynchronous Programming in C#

#38
post #26

>Prefer async/await over directly returning Task This one seems questionable to me. I've never been bitten by any of the cons mentioned[1], and it's even noted that doing it this way does incur performance costs. I've learned over the years that if the code path is very prolific, it pays to avoid the async state machine. I'm curious if others could expand on this one. [1] https://github.com/davidfowl/AspNetCoreDiagno…

Always using async/await is recommended to avoid _surprising_ behavior. If a method with a signature

Task Foo();

and it is not declared with async and it throws an exception, the exception is propagated directly to the call site. Think of this usage:

var getBarTask = Foo();

// do some other stuff

try { var bar = await getBarTask; }

catch (Exception ex) { handle exceptions }

Then if the Foo is not async the exception is thrown at 'var getBarTask = Foo();'. If it is declared with async the exception is wrapped inside of the Task object and thrown at the 'var bar = await getBarTask;'

Yes there is obviously a small performance cost. My guideline would be "always use async/await unless you call the method hunders or more times a second and the small performace cost becomes neglible. And always measure before you optimise.

edit: formating

Re: Asynchronous Programming in C#

#39

Earlier quoted context omitted.

.NET Core and later has ValueTask for that usecase.

but shouldnt it be that ValueTask is used everywhere by default and class "exists for some usecase"?

It kind of depends. Class is safer because you can have multiple calls to await and the TPL was designed to be mostly as safe as possible by default....but yeah, it does hurt that its not alloc free.

Re: Asynchronous Programming in C#

#40

The sync over async issue is a real common problem for me when trying to get a large older codebase converted to async and you can't just do it all at once. You still need support non async callers and you want to share code between the new async version and the old sync versions it makes it really difficult to do so. Say you have a db layer you want to move to async but you still have to support a sync api over that…

Database operations should be async, you shouldn't consume them synchronously, as they do IO. Async/Await came out in 2012, almost a decade ago (and with great first party library support, I might add). Moralizing aside, sometimes you do want to call async APIs as synchronous code. I don't think there should be a synchronous version of the API implemented as well, you just need to do var myValue = DoSomethingAsync().…

"var myValue = DoSomethingAsync().ConfigureAwait(false).Result;"

In my view there should be a built-in keyword to do this right. It's too easy to get this wrong and even worse possible problems only show up rarely.

Post reply on HN