News for hackers. Stuff that matters.
Re:Asynchronous Programming in C# by cmpb on Friday September 24, 2021 @10:11AM (#28642609)
>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/AspNetCoreDiagnosticScenarios/b...

Re:Asynchronous Programming in C# by jayd16 on Friday September 24, 2021 @10:39AM (#28643047)
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# by MaXtreeM on Friday September 24, 2021 @10:43AM (#28643110)
Always using async/await is recommended to avoid _surprising_ behavior. If a method with a signature

Task<Bar> 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# by ziml77 on Friday September 24, 2021 @02:20PM (#28646012)
It's actually the case that's marked async that surprises me more. But I don't think the difference has ever mattered in code that I've written or worked with.

The reason that the non-async case makes sense to me is that I know there's usually going to be some synchronous code execution before the function I'm calling has to go async. And in that case I expect the code the executed before going async to come up the stack where I called it instead of where I'm awaiting it. And of course I expect exceptions beyond that to only be able to be retrieved when I await the task since the call stack will be rooted in the event loop after going async.

Re:Asynchronous Programming in C# by rawling on Friday September 24, 2021 @12:06PM (#28644272)
This surprised me. When they wrote LINQ and iterables, MS went to great lengths to ensure exceptions that could be thrown immediately (before iterating) were. I wonder why async/await are the opposite.
Re:Asynchronous Programming in C# by jkulubya on Friday September 24, 2021 @02:16PM (#28645958)
I don’t think I’d have a philosophical problem with throwing both synchronously and asynchronously when using async/await. After all, the act itself of queuing some work with a possible future result does seem like something that can fail. But the dotnet team (or c# compiler team, not sure) helped devs out by promising not to throw on the queuing the work bit when using async/await, and only throw at the point where the result should ordinarily be ready.

If you don’t use async/await, then I’m not sure how else they can help. By returning a task without async, the dev claims that they’re smart enough to safely kick off some async work and possibly provide a result later. But in the act of kicking off the work, you break?

Re:Asynchronous Programming in C# by Salgat on Friday September 24, 2021 @12:11PM (#28644372)
Unless you're doing awaits in a tight loop of thousands/millions of calls, the overhead of the state machine is almost non-existent, which leads to the next question, what are you doing that requires await in a tight loop of that many calls? The whole point of await is to use it to yield a thread while waiting on a long running operation, if your await returns nearly instantly then use the synchronous version and avoid the overhead.
Re:Asynchronous Programming in C# by zmj on Friday September 24, 2021 @03:51PM (#28647016)
I've run into this in code that completes synchronously in the common case, but falls back to an async implementation - think caching. The simple way to write this creates a state machine even on the synchronous path.

It's possible to work around this efficiently by pulling the async code into a separate method and using ValueTask for the outer method return type.