Task or Task<TResult> object is awaitable, so we can use await key on those whose return value is Task or Task<TResult>.
Task or Task<TResult> are the most frequently-used awaitable object.
We also can define our own awaitable object.The object should has below qualification.
- It has a GetAwaiter() method (instance method or extension method);
- Its GetAwaiter() method returns an awaiter. An object is an awaiter
if:- It implements INotifyCompletion or ICriticalNotifyCompletion
interface; - It has an IsCompleted, which has a getter and returns a Boolean;
- it has a GetResult() method, which returns void, or a result.
- It implements INotifyCompletion or ICriticalNotifyCompletion
My question is that why Microsoft didn’t provide a interface to constrain these awaitable object?
The current method to implement awaitable object is a little complicated.
It is best answered in Lucian Wischik’s blog post Why must async methods return Task?
In summary (and I am not doing the blog post justice, you should read it), the issue is that
Taskalready exists, so introducing an interface would meanTaskor the interface, a decision that doesn’t matter much.Task.The impact from the above is so massive that it doesn’t make sense to provide an interface.