Что не так с этой реализацией Awaiter в Unity3D?

#c# #unity3d #async-await #task

#c# #единство 3d #асинхронный-ожидание #задача #unity3d #асинхронное ожидание

Вопрос:

Итак, я пытался создать простую ожидаемую структуру, которая позволяла бы мне возвращать bool:

 // define a special container for returning results
public struct BoolResult {
    public bool Value;
    public BoolAwaiter GetAwaiter () {
        return new BoolAwaiter(Value);
    }
}

// make the interface task-like
public readonly struct BoolAwaiter : INotifyCompletion {
    private readonly bool _Input;

    // wrap the async operation
    public BoolAwaiter (bool value) {
        _Input = value;
    }

    // is task already done (yes)
    public bool IsCompleted {
        get { return true; }
    }

    // wait until task is done (never called)
    public void OnCompleted (Action continuation) => continuation?.Invoke();

    // return the result
    public bool GetResult () {
        return _Input;
    }
}
  

И я использовал его как:

 private async BoolResult LoadAssets (string label) {
    //
    // some await asyncFunction here
    //

    // then at the end
    return new BoolResult { Value = true };
}
  

Но я все еще получаю эту ошибку компиляции:

error CS1983: The return type of an async method must be void, Task or Task<T>

Я думал, мое BoolResult уже было похоже на Задачу? В чем здесь проблема?

Комментарии:

1. Является BoolResult Task или Task<T> ?

2. черт возьми, у меня был длинный ответ в процессе… ну что ж; короткая версия: ваш тип доступен для ожидания на стороне потребителя, т. Е. await someBoolResult — Но вам нужен дополнительный клей, чтобы он работал на стороне производителя , т. Е. async BoolResult в сигнатуре метода. Однако код, который вы показываете, на самом деле не нуждается async в подписи — если вы удалите async из private async BoolResult , он должен работать и должен быть доступен для ожидания у потребителя

3. @MarcGravell Я не был полностью уверен в дубликате, так как затем я нашел это , которое предполагает, что должно поддерживаться что-то более похожее на этот код. Было ли это закрытие хорошим?

4. @CamiloTerevinto да, я думаю, что это хорошо — я просто добавил немного контекста / разъяснений о производителе и потребителе. Ссылка, на которую вы разместили, также говорит о consumer, что опять же: прекрасно; фактический вопрос здесь и в завершении обновления : о производителе . Итак: да, закрыть — это нормально, я думаю

5. так же, как некоторые рекомендации для @bitinn — количество раз, когда вы должны запускать свой собственный awaitable, теперь практически равно нулю; У меня есть незавершенный (т. Е. Незавершенный) пост в блоге, в котором подробно рассказывается об этом, но, если возможно: предпочитайте ValueTask<bool> . Есть отличные способы сделать это, которые обходят Task даже в неполном случае.