In C#7, how can I “roll my own” Task-like type to use with async?

I couldn’t find any good tutorial yet.
But you can look at the compiler unittests which create such task-like types (look for “[AsyncMethodBuilder”).

The starting point is to create a type and mark it as task-like with an attribute like [AsyncMethodBuilder(typeof(MyTaskBuilder))].
Then you need to define your own MyTaskBuilder type. It must implement a certain pattern (see below). That is the same pattern implemented by the regular AsyncMethodBuilder type which supports regular Task.

class MyTaskBuilder
{
    public static MyTaskBuilder Create() => null;
    public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine { }
    public void SetStateMachine(IAsyncStateMachine stateMachine) { }
    public void SetResult() { }
    public void SetException(Exception exception) { }
    public MyTask Task => default(MyTask);
    public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine { }
    public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine { }
}

Update: a small spec for task-like types was added to the compiler documents.

Leave a Comment