Прочитать на английском

Поделиться через


Ошибка компилятора CS1986

Для типа "await" требуется, чтобы тип был подходящим методом GetAwaiter

Пример

Следующий пример приводит к возникновению ошибки CS1986:

using System.Runtime.CompilerServices;
using System;
using System.Threading.Tasks;

class Program
{
    static async Task M(MyTask<int> x)
    {
        var z = await x;
        System.Console.WriteLine(z);
    }
}

public class MyTask<TResult>
{
    readonly MyTaskAwaiter<TResult> awaiter;
    public MyTask(TResult value)
    {
        this.awaiter = new MyTaskAwaiter<TResult>(value);
    }
    public static MyTaskAwaiter<TResult> GetAwaiter() => throw new NotImplementedException();
}

public class MyTaskAwaiter<TResult> : INotifyCompletion
{
    TResult value;
    public MyTaskAwaiter(TResult value)
    {
        this.value = value;
    }
    public bool IsCompleted { get => true; }
    public TResult GetResult() => value;
    public void OnCompleted(Action continuation) => throw new NotImplementedException();
}

GetAwaiter Метод должен быть нестатичным методом с именем GetAwaiter и возвращать экземпляр объекта, реализующегоINotifyCompletion.

GetAwaiter должен реализовать INotifyCompletion интерфейс (и при необходимости ICriticalNotifyCompletion интерфейс) и вернуть тип, который сам предоставляет три члена [1]:

bool IsCompleted { get; }
void OnCompleted(Action continuation);
TResult GetResult(); // TResult can also be void

Исправление ошибки

Причина возникновения CS1986 в примере заключается в том, что GetAwaiter метод является static. Чтобы исправить эту ошибку static , удалите модификатор (и правильно реализуйте метод):

public class MyTask<TResult>
{
    readonly MyTaskAwaiter<TResult> awaiter;
    public MyTask(TResult value)
    {
        this.awaiter = new MyTaskAwaiter<TResult>(value);
    }
    public MyTaskAwaiter<TResult> GetAwaiter() => awaiter;
}

См. также

[1] ожидает ничего;