-1

I have a base class that defines an abstract method that returns a Task.

public abstract class BaseClass
{
    public abstract Task DoSomething();
}

I can make a class that implements the abstract method in these two different ways.

public class Example1 : BaseClass
{
    public override Task DoSomething()
    {
        return Task.CompletedTask;
    }
}

or like this

public class Example2 : BaseClass
{
    public override async Task DoSomething()
    {
    }
}

Notice that the first returns a completed task, the second includes the async keyword and doesn't have a return statement. Is there any difference between the two?

Mike
  • 11
  • 3
  • 1
    In first return type is needed, in second visual studio say `warning CS1998: This async method lacks 'await' operators and will run synchronously.` if you does not use any await in that method. More info https://stackoverflow.com/questions/13243975/suppress-warning-cs1998-this-async-method-lacks-await – daremachine May 28 '20 at 01:22
  • better explain https://developers.de/blogs/damir_dobric/archive/2014/03/04/be-aware-of-await-lacks-cs1998.aspx – daremachine May 28 '20 at 01:24
  • @daremachine - thank you for your comments. I didn't get the warning but your explanation makes sense. – Mike May 28 '20 at 02:03
  • The warnings are in build output or if you have method name underlined in VS, get mouse pointer on that. Glad to help. – daremachine May 28 '20 at 02:06
  • I would use the former example. It is clear, simple, and easy to understand. – mjwills May 28 '20 at 02:09

1 Answers1

2

There is significant difference in the code that gets generated. By merely adding the async keyword the method gets compiled very differently.

Here's effectively what the compiler produces:

public class Example2 : BaseClass
{
    private struct DoSomethingStateMachine : IAsyncStateMachine
    {
        public int _state;

        public AsyncTaskMethodBuilder _builder;

        private void MoveNext()
        {
            try
            {
            }
            catch (Exception exception)
            {
                _state = -2;
                _builder.SetException(exception);
                return;
            }
            _state = -2;
            _builder.SetResult();
        }

        void IAsyncStateMachine.MoveNext()
        {
            this.MoveNext();
        }

        private void SetStateMachine(IAsyncStateMachine stateMachine)
        {
            _builder.SetStateMachine(stateMachine);
        }

        void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
        {
            this.SetStateMachine(stateMachine);
        }
    }

    public override Task DoSomething()
    {
        DoSomethingStateMachine stateMachine = default(DoSomethingStateMachine);
        stateMachine._builder = AsyncTaskMethodBuilder.Create();
        stateMachine._state = -1;
        AsyncTaskMethodBuilder _builder = stateMachine._builder;
        _builder.Start(ref stateMachine);
        return stateMachine._builder.Task;
    }
}
Enigmativity
  • 113,464
  • 11
  • 89
  • 172