66

I'm unable to declare

interface IMyInterface
{
   async Task<myObject> MyMethod(Object myObj);
}

The compiler tells me:

  • The modifier async isn't valid for this item
  • The async modifier can only be used for methods that have a body

Is this something that should be implemented, or does the nature of async & await prohibit this from ever occurring?

Marc.2377
  • 7,807
  • 7
  • 51
  • 95
makerofthings7
  • 60,103
  • 53
  • 215
  • 448

4 Answers4

70

Whether a method is implemented using async/await or not is an implementation detail. How the method should behave is a contract detail, which should be specified in the normal way.

Note that if you make the method return a Task or a Task<T>, it's more obvious that it's meant to be asynchronous, and will probably be hard to implement without being asynchronous.

From https://stackoverflow.com/a/6274601/4384

stuartd
  • 70,509
  • 14
  • 132
  • 163
  • 2
    This could get ugly. Async method name usually should end with an `Async` suffix. Not able to enforce async implementation for a method defined in a interface (with `Async` in the name) means that we could have a non-async methods with Async suffix in their names. Or if we chose not to do so, we would have async methods without async suffix in their names. Is there a convention that people follow? – GiriB Mar 13 '19 at 11:10
  • Yes it is just convention, and like all conventions some people choose their own way. However as in the quote above, returning a `Task` / `Task` vs `void` / `T` does make it more obvious, and harder to implement incorrectly. – stuartd Mar 13 '19 at 11:43
  • 2
    @GiriB - whether a method is implemented with or without `async` is of no concern to the caller. You can be asynchronous without , and synchroinous with that keyword. – H H Jul 14 '21 at 21:42
21

Whether or not your implementation is async, has no relevance to your interface. In other words, the interface cannot specify that a given method must be implemented in an asynchronous way.

Just take async out of your interface and it will compile; however, there is no way to enforce asynchronous implementation just by specifying an interface.

Roy Dictus
  • 32,551
  • 8
  • 60
  • 76
7

If you have an interface with two implementations (one that is truly async and the other that is synchronous) this is what it would look like for each implementation - with both returning a Task<bool>.

public interface IUserManager
{
    Task<bool> IsUserInRole(string roleName);
}

public class UserManager1 : IUserManager
{
    public async Task<bool> IsUserInRole(string roleName)
    {
        return await _userManager.IsInRoleAsync(_profile.Id, roleName);
    }
}

public class UserManager2 : IUserManager
{
    public Task<bool> IsUserInRole(string roleName)
    {
        return Task.FromResult(Roles.IsUserInRole(roleName));
    }
}

If it is a void method you need to return Task.CompletedTask; from the non async method (I think .NET 4.5 and later)

See also : Return Task<bool> instantly

ANeves
  • 6,219
  • 3
  • 39
  • 63
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
1

The async modifier is an 'implementation detail', it affects how a method can do stuff asynchronously, not if it does so.

So async has no business being inside an interface.

interface IService { Task DoSomethingAsync(); }

class A : IService { public async Task DoSomethingAsync() { ... } }

class B : IService { public Task DoSomethingAsync() { ... } }

Classes A and B are both perfectly valid. Both methods are awaitable. A consumer of the interface doesn't know or care if they use async.

B.DoSomethingAsync() can be and probably will be asynchronous.

H H
  • 263,252
  • 30
  • 330
  • 514