1

I am working with a third-party dll which exposes methods which return Task and Task<T>. I don't have any control over this assembly or the interface, and I assume the author assumed everything would need to be async since the naming of the methods are *Async() as shown below.

Given that, how do I properly implement the interface if I don't actually have any asynchronous code running?

public interface IFoo
{
    Task DoWorkAsync();

    Task<int> GetValueAsync();
}

My attempt was the following:

public class FooBar : IFoo
{
    public async Task DoWorkAsync()
    {
        // Do Some Work

        await Task.Yield();
    }

    public async Task<int> GetValueAsync()
    {
        // Do Some Work
        var result = ...;

        return Task.FromResult(result);
    }
}

Additionally:

  • Was the author correct in exposing only methods that returned Task/Task<T>?
  • Was the author correct in suffixing method names with *Async()? Code analysis doesn't complain if I write an async method without appending Async to the name.
michael
  • 14,844
  • 28
  • 89
  • 177
  • 2
    I'd say yes on calling methods `Async`. Makes it clear and simple, esp. when you're upgrading and trying to keep things backwards compatible to have methods `GetSomething` and `GetSomethingAsync`. – rbm Nov 14 '16 at 19:54
  • I generally do the former of your two approaches. If there's nothing to await then there's nothing to await. Seems unnecessary, but 3rd party libraries are what they are. – David Nov 14 '16 at 19:55
  • @David: There aren't two approaches shown, those are two different methods, one of which technically doesn't have a return, which is why it is just `Task` instead of `Task`. – michael Nov 14 '16 at 19:58
  • @michael: And of those two methods I usually use the approach taken in the first method, simply awaiting `Task.Yield()`. Whether or not you want to do that in the second method is I guess your personal preference. I'd be interested to know if there's any real benefit in one over the other, but I doubt there's any discernible difference. – David Nov 14 '16 at 20:04
  • See also https://stackoverflow.com/questions/32932391/implement-async-interface-synchronous. These address the technical question of how to implement an interface like this when your own code isn't inherently asynchronous. If you are asking how one _should_ do it, that is primarily opinion based and too broad a question for Stack Overflow. – Peter Duniho Nov 14 '16 at 20:28

1 Answers1

3

If you don't have async work to do don't include the async keyword. Your GetValueAsnyc function was almost correct, you just needed to drop the async. For your DoWorkAsync you should just not mark the method async and return a completed task.

public class FooBar : IFoo
{
    public Task DoWorkAsync()
    {
        // Do Some Work

        //If you can use .NET 4.6
        return Task.CompletedTask;

        //For older versions, the thing you pass in does not matter, I like to use bool.
        return Task.FromResult(false);
    }

    public Task<int> GetValueAsync()
    {
        // Do Some Work
        var result = ...;

        return Task.FromResult(result);
    }
}

However, if your code is slow and you end up blocking the UI for a long period of time I would consider looking in to if you can re-write your code as actually being async or perhaps wrapping the code in to a background thread, but I would only do a background thread if it was a last resort.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431