2

How can I create a class interface with async and sync methods?

I'm creating a interface service that implements:

public Interface IService<T> where T : class{
    T Get(int id);
    bool Add(T entity);
    bool Remove(int id);
    bool Update(T entity);
}

But some operations in the application context are async methods for instance: userManager.CreateAsync(user, password) in the UserManager Class.

And then I do have 2 options.

  1. use ...GetAwaiter().GetResult(); to make a async call inside a sync method.
  2. Make entire application and my interface async Tasl<bool> async Add(T entity){ ... }

Both of them are has its owns problem.

  1. ...GetAwaiter().GetResult(); can generate some undesired deadlocks as said here
  2. I need to make all methods chain up to be async.

Is possible that interface can provide methods for sync and async methods?

Daniel Santos
  • 14,328
  • 21
  • 91
  • 174
  • 1
    The best option is not calling async methods inside a sync method. You have to think that what is the use of having a sync method that needs to call an async one inside of it. – Damitha Shyamantha Mar 10 '18 at 19:09

2 Answers2

11

Async methods are simply methods that return a Task instead of a raw value. That's all. Naturally, you can have your interface contain both a void Update() and Task UpdateAsync() if you want, thus supporting both sync and async operations.

However, that isn't necessarily the best course of action. If your operations rely on async operations, like your CreateUserAsync example, the code you use to turn them into synchronous operations can be flaky and dangerous. Async code is best served by being async all the way up, and letting the original caller decide on when to await.

When you say "Both [options] have their own problems", say, but when you spell them out, it's clear that they're not really equal problems. "Can generate deadlocks at runtime" vs. "requires rewriting more of my code to be async" is, for me, a no-brainer. Go async all the way.

Avner Shahar-Kashtan
  • 14,492
  • 3
  • 37
  • 63
2

Let developer studio extract an interface for you and you'll see your answer

class MyClass
{
    public async Task<int> GetValueAsync(int i)
    {
        await Task.Delay(TimeSpan.FromSeconds(1));
        return i;
    }
}

right click on MyClass. Select "quick actions and refactoring" and let it create an interface for you. The result is something like:

interface IMyClass
{
    Task<int> GetValueAsync(int i);
}

I guess this answers your question

Harald Coppoolse
  • 28,834
  • 7
  • 67
  • 116