Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
'await' requires that the type have a suitable 'GetAwaiter' method
Example
The following sample generates 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();
}
A GetAwaiter
method must be a non-static method named GetAwaiter
and return an instance of an object that implements INotifyCompletion
.
A GetAwaiter needs to implement the INotifyCompletion
interface (and optionally the ICriticalNotifyCompletion
interface) and return a type that itself exposes three members [1]:
bool IsCompleted { get; }
void OnCompleted(Action continuation);
TResult GetResult(); // TResult can also be void
To correct this error
The reason CS1986 is raised in the example is that the GetAwaiter
method is static
. To correct this error, remove the static
modifier (and correctly implement the method):
public class MyTask<TResult>
{
readonly MyTaskAwaiter<TResult> awaiter;
public MyTask(TResult value)
{
this.awaiter = new MyTaskAwaiter<TResult>(value);
}
public MyTaskAwaiter<TResult> GetAwaiter() => awaiter;
}
See also
[1] await anything;