What should I use as a dummy awaitable?

12,896

You misunderstand how async works. It's not part of the signature, so if you don't need the await, you don't actually have to use it. So even though you are providing a Task RunAsync() method, you can just write it without the async, for example:

virtual Task RunAsync()
{
  return Task.FromResult(false);
}

This still allows you to make an override that does in fact use await, like so:

override async Task RunAsync()
{
  await base.RunAsync();
  await DoSomeOtherStuffAsync();
}

This is the reason why the compiler gives you the warning - the async keyword is completely useless, and not part of the method signature. It's just a signal to the compiler that it's allowed to use the identifier await as a keyword, basically - to maintain backwards compatibility with older C# code.

EDIT:

As noted by Jeroen Mostert in the comments, from .NET Framework 4.6 on, the Task.CompletedTask property is public, so you can do this:

virtual Task RunAsync()
{
  return Task.CompletedTask;
}

So if you can use 4.6+, this is the newest, cleanest option. And of course, if you need the task to actually return a value, Task.FromResult is still there :)

Share:
12,896

Related videos on Youtube

David
Author by

David

Updated on September 15, 2022

Comments

  • David
    David over 1 year

    I have a Base class which provides a method with the following signature:

    virtual async Task RunAsync()
    

    Derived classes should override this implementation with something like

    public override async Task RunAsync()
    {
      await base.RunAsync();
      await this.DoSomethingElse();
    }
    

    Now the compiler gives me a warning that the Base.RunAsync is lacking an await statement. I want that my code is warning free, not suppressing warnings and that it runs without having to provide null checks even if the derived class doesn't provide an override implementation, therefore going with virtual Task RunAsync() (omitting the async keyword) is not possible.

    For now the implementation in the base method is await Task.Delay(0); which dismisses the compiler warning, yet is somehow not "clean" in my opinion. What is the right way to cope with this subject?

  • Jeroen Mostert
    Jeroen Mostert about 9 years
    @David: The framework does offer that -- it's Task.CompletedTask.
  • Jeroen Mostert
    Jeroen Mostert about 9 years
    Of course, I now see that's very, very recent -- from 4.6 onwards. Still, better late than never. :-)
  • Luaan
    Luaan about 9 years
    @David Well, it will always be a work-around - you're not doing any asynchronous work in an asynchronous method :D Both Task.Delay(0) and Task.FromResult(false) actually return a completed task immediately, so they are more or less equivalent (I avoid Task.Delay(0) - delay usually continues on a new thread unless called with 0, so it can be a bit confusing). But yeah, now that Task.CompletedTask is public, there's no reason for using the other workarounds. If you can move to 4.6, go for it.