You always need to be aware of "side-effects" and "determinism" in your code. If the side-effect (i.e. what happens when the code runs) can have an impact on something else (inserting, deleting rows, creating objects, etc) you need to be aware of the order of completion and control when it happens.
You also need to be aware of the determinism of your code (i.e. can I know that this thing will be there when I need it), again if its in question you need to control how your code executes.
Take for example processing records from a database. You must have the records before you can process them, so you must do them in that order. If the two processes are in different locations in your code (threads, callbacks, events, etc). The second function (processing the records) must be made aware of the state of the first function (getting the rows) usually done with flags, locks, semaphores, etc.
For determinism think of guard statements in a function. If my function needs to have a string and a not null object, I first check those conditions when we enter the function before I start calling methods on those objects (calling string.ToLower() is fine on a string, but bad on a null object). In this way I am doing runtime determinism to prevent errors in my code (such as NullReference, etc). The compiler performs its own compile time determinism, but it cannot be aware of the state of objects during execution so it only does its comparisons on operations (whether they are semantically valid or not).