I used it in cocos (long ago) because I didnt find any other means to control the stuff (like animations) tightly.
I hated it, it requires a bunch of loading code to prepare the actions, and when you need to interrupt it, cancel in the middle or something, it gets even more ugly. ( I dont remember very well thou)
In my engine, I have chainable tasks, the purpose of those (from my POV of course) is to use it when you need to execute some code that would be a rare if case in the game loop. Basically, having a loop full of IFs that almost never execute is ugly/poor code, so the tasks works perfectly for stuff like this, since in the game loop is just a tasker.update(delta); call. So I use it as a temporary code executer.
One of my tasks is a "delegate task", that basically executes a delegate till it returns false, making it very easy to create new tasks without having to derive a new class (just create a new method and plug on the delegate).
Chaining tasks is not as cute as I though it would be when I implemented it. Reusing tasks by reordering the chain is not so obvious and generally I end up with a few small tasks that are almost the same.
The fact that I prohibit myself from allocate memory at run time also requires pre initializing all tasks, with is also a pain in the ass. The task machine works with shared pointers so I basically initialize a bunch shared pointers with noop deleters.