Is there a rule as to which methods are best made async and which not?
Or, once you start using async would it be best to make ALL methods async?
Many methods could be either sync or async. But if you make a method that doesn't strictly need to be async async you give yourself the option of later making it actually return its result after a delay, say reading its answer from the web or asynchronously from disk.
Whereas later trying to convert sync-methods to async seems to sometimes require big changes to the structure of the whole program. If you depend on getting the answer right away there is no easy way to modify the code so it in fact returns the answer after a delay. Or is there?
A downside to async-methods I can see is that they are harder to debug of course.
I recently had to make a change that converted a few functions to be async. It was certainly annoying to propagate that back in all the signatures, but the biggest issues came with having code that was designed under the assumption that the code would be synchronous. It was difficult to rework the code in ways that would avoid issues with things like the fact that if I use a member variable, call one of these functions, and then use use that variable again, there's no longer a guarantee that the variable still has the same value.
And for issues like that I don't think that having async from the start would have helped much. Because if the signature said async but everything actually completed synchronously, it's possible that people would have been more conscious about those issues, but it's also very likely that plenty of cases would be missed. Testing wouldn't expose any problems unless the implementations were swapped out for code that was actually running asynchronously.
It's not easy to call what the right approach is. The best you can do is try to guess what the most likely future is and code for that. Violating the YAGNI principle can end up adding extra work and complexity and even reduced performance for no payoff later.
I've had similar situations where what initially seems like a simple change between async vs. sync can turn out to be a major redesign effort. Therefore I'm starting to lean on the idea that I should use more async -methods from the start than what I'm currently doing.
Part of the issue is that 'sync' is the default. I wonder if it would be better the other way. Because sync is the default it is easy to "simply" write sync methods in cases where async might be a better choice, and, that decisions is often hard to reverse later.
I'm working with JavaScript but I assume the issues and questions are similar as with c#.
I think the question could be rephrased as "When should I NOT use async methods?"
> use a member variable, call one of these functions, and then use use that variable again, there's no longer a guarantee that the variable still has the same value.
Could you expound upon this? Not sure I understand the context, but would like to. Are you assigning a value to a member variable by awaiting the return of an async method, not clear would cause you to lose the value.
The would say that asynchronous methods are mostly about orchestration and side-effects and non-asynchronous ones about computations.
If your computation code reach out to fetch data or trigger side-effects I’d take that as a sign of it being badly factored. Try to push the async parts up the stack to an orchestration layer, and keep the computation code “pure”
Another downside is the overhead created. Those “simple” async methods are translated into state machine classes under the hood. You could probably test performance and see if the value you get is worth it.
Or, once you start using async would it be best to make ALL methods async?
Many methods could be either sync or async. But if you make a method that doesn't strictly need to be async async you give yourself the option of later making it actually return its result after a delay, say reading its answer from the web or asynchronously from disk.
Whereas later trying to convert sync-methods to async seems to sometimes require big changes to the structure of the whole program. If you depend on getting the answer right away there is no easy way to modify the code so it in fact returns the answer after a delay. Or is there?
A downside to async-methods I can see is that they are harder to debug of course.