Подтвердить что ты не робот

Как заставить переопределить дочерние символы async в С# 5.0

Я работаю над системой, в которой ожидается, что несколько клиентских объектов реализуют определенную функцию через интерфейс, и я хочу, чтобы эта функция выполнялась асинхронно с продолжениями (я ожидаю, что реализации будут связаны с I/O-привязкой и хотите, чтобы все клиентские объекты выполнили эту функцию как можно скорее). Я использую Visual Studio Async CTP Refresh для SP1, с С# "5.0".

Какова рекомендуемая практика для обеспечения асинхронного поведения в дочерних объектах моего абстрактного класса (см. ниже)? Я не могу (по-видимому) применять использование методов "async" с использованием подхода виртуального метода. Мне может потребоваться только тип возврата "Задача". Означает ли это, что я не должен пытаться требовать асинхронного поведения вообще в дочерних объектах? В этом случае, если тип возврата будет просто "недействительным"?

Публичный интерфейс является неудачным последствием проектирования системы прямо сейчас, но это отдельная проблема. Очевидно, я не мог сдержать кого-либо асинхронным, который обходит "BaseFoo" и просто реализует интерфейс "IFoo".

Вот код:

public interface IFoo
{
    void Bar(); //NOTE: Cannot use 'async' on methods without bodies.
}

public abstract class BaseFoo : IFoo
{
    public async void Bar()
    {
        await OnBar(); //QUESTION: What is the right "async delegation" pattern?
    }

    protected virtual async Task OnBar()
    {
        await TaskEx.Yield();
    }
}

public class RealFoo : BaseFoo //NOTE: May be implemented by 3rd party
{
    protected override async Task OnBar()
    {
        //CLIENT: Do work, potentially awaiting async calls

        await TaskEx.Yield(); //SECONDARY QUESTION: Is there a way to avoid this if there are no 'awaits' in the client work?
    }
}
4b9b3361

Ответ 1

Является ли метод реализованным с помощью async/await или нет, является деталью реализации. Как должен вести себя метод - это детали контракта, которые должны быть указаны обычным способом.

Обратите внимание, что если вы вернете метод Task или Task<T>, более очевидно, что он должен быть асинхронным и, вероятно, будет трудно реализовать, не будучи асинхронным.

С другой стороны, если существует реализация (например, для целей тестирования), где выражения await никогда не будут неполными, почему вы хотите заставить кого-то писать метод асинхронного вызова без вызовов await? Вы ожидаете, что реализации будут привязаны к IO, но, возможно, будут специальные случаи, когда реализации хотят использовать жестко кодированные данные и т.д.

В основном вы должны обрабатывать это в документации для этого метода - если вы не можете доверять разработчикам, чтобы прочитать это, у вас нет шансов в любом случае: (

Ответ 2

В ответ на ответ Jon, если вы следуете Асинхронный шаблон на основе задач, ваши имена методов должны быть суффиксом Async, который сам документирует, что это асинхронный метод.

Если вы реализуете интерфейс

public interface IFoo
{
    Task BarAsync();
}

должно быть очевидно, что это должно быть реализовано с помощью ключевого слова Async.