Правильная переопределение метода asyn c в C# - PullRequest
0 голосов
/ 28 мая 2020

У меня есть базовый класс, который определяет абстрактный метод, возвращающий задачу.

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

Я могу создать класс, реализующий абстрактный метод двумя разными способами.

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

или примерно так

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

Обратите внимание, что первый возвращает завершенную задачу, второй включает ключевое слово asyn c и не имеет оператора return. Есть ли разница между ними?

1 Ответ

1 голос
/ 28 мая 2020

Существует значительная разница в генерируемом коде. При простом добавлении ключевого слова async метод компилируется по-другому.

Вот, что фактически производит компилятор:

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;
    }
}
...