Must we define methods and async when we don't know whether the implementation is synchronous or asynchronous?

softwareengineering.stackexchange https://softwareengineering.stackexchange.com/questions/391379

  •  24-02-2021
  •  | 
  •  

Domanda

I think I know the answer to this, but it's particular enough that I don't want to go telling other people stuff until I'm 100% certain.

Suppose I have a class with some dependency:

public interface IDependency
{
    int DoSomething(string value);
}

public class DependsOnSomething
{
    private readonly IDependency _dependency;

    public DependsOnSomething(IDependency dependency)
    {
        _dependency = dependency;
    }

    public int GetSomeValue(string input)
    {
        return _dependency.DoSomething(input);
    }
}

IDependency is an abstraction. I haven't yet determined what its implementation will be. I don't know whether it will be CPU-bound or perhaps make some API call.

What's more, the implemenation of IDependency could have its own dependencies, and the same could be true of those. They may or may not call async methods.

Would it be correct to say that

  • If I consider it likely that something, somewhere will be async, that I should make all of these methods async?
  • If nothing in any of the dependencies is async but at some point that changes, and I want to take advantage of that opportunity to free up a thread instead of letting it wait, I would need to go back through all of my methods and make everything async?

Generally I can plan for what does or doesn't need to be asynchronous, but I'm trying to understand the potential cost of a) guessing synchronous and b) guessing wrong.

Is my understanding of this correct?

One workaround to the problem might be, in some cases, to define both synchronous and asynchronous methods on interfaces. But that feels wrong because then the interface is describing implementation details, and if the underlying implementation isn't really asynchronous then my interface is lying. (And it could lead to me or someone else writing even more async methods to call something that isn't really async.)

È stato utile?

Soluzione

The problem, of course, is that in .NET it's "async all the way down," meaning that once you go down the async path, your entire call chain must be async.

So your decision must be needs-based.

How do you decide which methods to make async? A good rule of thumb is the 50ms rule. If it is likely that the method is going to take more than 50 milliseconds to execute, make it async. Microsoft applied this rule to their WinRT platform, and found that about 10 percent of the method calls needed to be async.

This is mostly a UI rule. If you're talking to a server, the metrics are a bit different.

Further Reading
Should I make a fast operation async if the method is already async?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
scroll top