3 ms·
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
by MaXtreeM 5y ago
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
- rawling 5y agoThis 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.
- jkulubya 5y agoI 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?
- ziml77 5y agoIt'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.