One common mistake has to do with the implementation of CompletedSynchronously property of IAsyncResult. People writing their own classes implementing IAsyncResult need to be careful returning the correct value and neither ‘always true’ nor ‘always false’ is a good idea in most cases. According to the design of the async API pattern, CompletedSynchronously is supposed to be 'true' if the AsynCallback is called from inside the ‘begin’ method, on the same thread. In all other cases CompletedSynchronously must be 'false'. An incorrect value could lead to deadlocks.
The reason for existence of CompletedSynchronously property in IAsyncResult is to allow callers of asynchronous components chain asynchronous operations (completed synchronously) without consuming stack and avoid keeping objects alive longer than needed. Without this knowledge(whether or not an async operation completed synchronously) the caller has to call the next operation from the callback of the previous one:
Caller Component1.BeginMethod AsyncCallback Component1.EndMethod Component2.BeginMethod AsyncCallback Component2.EndMethod