I recently learned about the possibility to have custom awaitable types and as this question and Stephen Toub states, there are several requirements to be an awaitable type.
So if a type T
wants to be awaitable it must
- expose an parameterless method
GetAwaiter
that returns a valid awaiter
and if a type A
wants to be a valid awaiter it must
- Implement the
INotifyCompletion
interface - Provide a boolean property called
IsCompleted
- Provide a parameterless
GetResult
method that returnsvoid
orTResult
So now I'm asking if all that is required to be an awaitable type, why isn't that part of some interfaces like
public interface INotifyCompletion
{
bool IsCompleted { get; }
void OnCompleted(Action continuation);
}
public interface IAwaiter : INotifyCompletion
{
void GetResult();
}
public interface IAwaitable<TAwaiter> where TAwaiter : IAwaiter
{
TAwaiter GetAwaiter();
}
public interface IAwaiter<TResult> : INotifyCompletion
{
TResult GetResult();
}
// this would probably not necessary but would likely help to identify
// awaitables that return a value
public interface IAwaitable<TAwaiter, TResult> where TAwaiter : IAwaiter<TResult>
{
TAwaiter GetAwaiter();
}
I also do understand that the compiler does not need it, since it can check all that at compile time without any penalty. But since there is the INotifyCompletion
interface for the OnCompleted()
method, why isn't the rest of the interface for awaitables and awaiters packed in some interfaces?
This would most likely help to inform programmers how to implement this.
I also know that one can make an type awaitable by providing an extension method that return a valid awaiter, but again why isn't the whole interface for an awaiter packed in a single interface but has holes (i.e. the IsCompleted
property is not part of any interface but required)?