error declared? Where is it being set? Is it being set in a global scope or a local scope? That is, did you make two copies of it, one global and one local and only set the local one? Basically, I think that
abs(error) > 25 never happens. I would add some statement above that loop to give you the value of error before it's first called.
Now that we have the linear programming questions covered, let's cover the ones specific to multithreading: race conditions. Assuming you've done everything else right, you may be running into a quirk of how threads of execution work. They do not happen simultaneously. One runs for a while, then yields the processor so another can run for a while. What I suspect is happening is everything is initialized,
error is initialized to 0, and your main thread starts running. It calls Move(1000) which I suspect sets a target value of 1000 and starts a task called Forward? But the main thread doesn't immediately yield after scheduling Forward to start, so it keeps going into the ForwardWait function, sees that error hasn't been changed from its initial 0 value yet (as that is done in Forward, which hasn't started yet), exits ForwardWait, stops task Forward, then calls Move(-500) which schedules Forward to start again with a new target value. Finally, having exhausted all commands, task main is forced to yield, at which point Forward starts with the last target value it was given: -500.
Basically, you need an end condition for ForwardWait that requires Forward to have actually executed instead of checking a 0-initialized variable. Multithreading is... often non-intuitive.