With protothreads, you split up your long going task into several steps. This may be searching the next level in a tree instead of the whole subtree, or processing of a message queue, garbage collection or whatever.
The basic idea is that you keep track of the last time you executed what you want, and continuously check against the current time to see if it's time do do some more work.
Here is some c style code which presumes that variables are edclared and initialized and that a function called currentTime exists which gives continuous relative indication of time (such as the number of milliseconds since the program started):
if (currentTime() - previous1 >= interval1)
previous1 = currentTime();
// do something for task 1
if (currentTime() - previous2 >= interval2)
previous2 = currentTime();
// do something for task 2
This logic can of course be encapsulated by a class, much like I've done for the http://wiring.org.co/ project here https://github.com/WiringProject/Wiring/blob/master/framework/libraries/TimedAction/TimedAction.cpp.
NB: The accuracy and resolution of currentTime() will be a restrictive factor in what you can do.